Comments 6
Спасибо за статью! Но почему интерфейс калькулятора имеет вид
type Calculator[T any, V any] interface {
Add(operand V) T
Sub(operand V) T
Mul(operand V) T
Div(operand V) T
Value() V
}
А не:
type Calculator[V any] interface {
Add(operand V) Calculator[V]
Sub(operand V) Calculator[V]
Mul(operand V) Calculator[V]
Div(operand V) Calculator[V]
Value() V
}
Или я проморгал сакральный смысл?
На эту тему есть в начале и в конце ремарки. И если бы интерфейс был таким, как вы описываете, то, к примеру, сигнатура метода Add()
должна была бы быть следующей:
func (c Calc) Add(operand float64) Calculator[float64]
В общем, перечитайте заключение, там довольно подробно постарался расписать, если все еще останутся вопросы - пишите, постараюсь уточнить или внести правки.
UPD: Для устранения шероховатостей подправлю последний пример, дабы было понятно, что там не требуется второй параметр.
Вот поэтому не все в сообществе были рады появлению дженериков. Потому что понимали, что немедленно найдутся люди, которые будут писать код так:
func ProcessCommands[T Calculator[T, V], V any](calc Calculator[T, V], commands ...Command[T, V]) Calculator[T, V] {
// ...
}
func ProcessCommands[T any, V any](calc Calculator[T, V], cast func(*T) Calculator[T, V], commands ...Command[V]) Calculator[T, V] {
// ...
}
А нам потом это поддерживать.
Ну зачем так делать? Go задумывался как простой язык. Да, многословный. Но простой. Пожалуйста, не пишите на нем как на джаве.
Затем, что вы путаете теплое с мягким. Вся статья не на тему - как неудобно написать калькулятор, а на тему - что делать, если уже есть чужой пакет, для которого нужно применить обобщенный алгоритм. Неужели это не ясно из заключения?
UPD: Внес дополнение к примечанию, надеюсь, это прояснит ситуацию для тех, кто будет читать позднее.
Это как раз ясно. Я о том, что мне не близок вот этот подход:
Можно было бы применить копипасту или кодогенерацию, но тот червь, что живет в моем мозгу, опять начал зудеть и нашептывать что-то про дженерики, не давая спать по ночам.
Простое решение было, но вы его не выбрали. А выбрали вот это, где дженерик на дженерике сидит и дженериком погоняет. Я за то, чтобы в продакшене такого кода было как можно меньше.
Go: обобщенные алгоритмы и типы