тип для работы с деньгами и каждый его метод имеет два варианта – возвращающий ошибку и инициирующий панику. Я сейчас вот так называю, но AddE выглядит несколько уродливо:
func (m *Money) Add(value ...Money) Money {...
func (m *Money) AddE(value ...Money) (Money, error){...
Undefined behaviour. К рублям прибавили евро, не определив обменный курс.
Тогда же нельзя будет строить цепочки типа e = Add(a).Add(b).Sub(с).Mul(7)
это антипаттерн в го
squirrel - это антипаттерн? Не знал 😊
result, err := doSomething() if err != nil { ... } some, err := result.doSomethingWithResult() if err != nil { ... }
ну по крайней мере в го я этого нигде не видел
Получим код на порядок более длинный и менее наглядный на ровном месте.
так а как он ошибки хэндлит?
тогда уж res, err := Add(a).Add(b).Sub(с).Mul(7).Exec()`
да. это плохо, но другого пути нет. вернее есть, но его сложно придерживаться
Пользователь может не использовать методы с паникой, если ему это критично. Но код вырастет в разы местами.
А смысл какой, если оно упадет на первой точке когда рубли сложат с долларами?
оно не должно вообще ничего делать до вызова Exec, в этом вся соль билдера
users := sq.Select("*").From("users").Join("emails USING (email_id)") active := users.Where(sq.Eq{"deleted_at": nil}) sql, args, err := active.ToSql() sql == "SELECT * FROM users JOIN emails USING (email_id) WHERE deleted_at IS NULL"
то есть это такой набор параметров для операции
Не знаю, не копал. У нас с ним не задалось в итоге - делали свое подмножество.
Я понимаю, а реализовать-то как? Хранить error внутри Money и "вываливать" его наружу только в момент Exec()?
ага, в общем то так все и делают
Но тоже выглядит на троечку, если надо a.Add(b) сделать a.Add(b).Exec() - не слишком интуитивно 😞
Я бы тогда так задизайнил: с = a.Add(b) if с.err != nil { error handling }
а чем это лучше c, err := a.Add(b) ?
Тем, что цепочка будет работать, так как Add возвращает тот же тип, что и на входе. И Exec не нужен.
почему так не делают обычно?
Обсуждают сегодня