У Go нет дженериков. Ваши возможности:
Интерфейс диспетчеризации
type CanTraverse interface {
Get(int) interface{}
Len() int
}
type Colours []Colour
func (c Colours) Get(i int) interface{} {
return c[i]
}
func (c Colours) Len() int {
return len(c)
}
func doSome(v CanTraverse) {
for i := 0; i < v.Len; i++ {
fmt.Println(v.Get(i))
}
}
Тип переключатель, как @Plato предложил
func doSome(v interface{}) {
switch v := v.(type) {
case *[]Colour:
//Do something with colours
case *[]Brush:
//Do something with brushes
default:
panic("unsupported doSome input")
}
}
Отражение как fmt.Println() делать. Отражение очень мощное, но очень дорогое, код может быть медленным. Минимальный пример
func doSome(v interface{}) {
value := reflect.ValueOf(v)
if value.Kind() == reflect.Slice {
for i := 0; i < value.Len(); i++ {
element := value.Slice(i, i+1)
fmt.Println(element)
}
} else {
fmt.Println("It's not a slice")
}
}
Нет! :) Его плохая практика. если я добавляю новый тип, функция doSome() нуждается в модификации. –
Я думаю, что это * хорошая практика, потому что она заставляет вас явно выражать 'doSome()', а не предполагать поведение. Если вы хотите, чтобы doSome всегда создавал EMPTY-фрагменты, вы могли бы использовать 'b: = make ([] Brush, 3)' вместо 'doSome (& b)' – Plato