У меня есть функция.

func doSome(v interface{}) {

}  

Если я передаю по указателю фрагмент структуры в функцию, функция должна заполнить фрагмент.

type Color struct {
}
type Brush struct {
}

var c []Color
doSome(&c) // after с is array contains 3 elements type Color

var b []Brush
doSome(&b) // after b is array contains 3 elements type Brush

Может мне нужно использовать отражение, но как?

3
Oleg Khamov 7 Сен 2016 в 10:30

3 ответа

Лучший ответ
func doSome(v interface{}) {

    s := reflect.TypeOf(v).Elem()
    slice := reflect.MakeSlice(s, 3, 3)
    reflect.ValueOf(v).Elem().Set(slice)

}  
4
Sridhar 7 Сен 2016 в 15:37

В 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")
    }
}
1
Uvelichitel 7 Сен 2016 в 13:20

Машинка !!

package main
import "fmt"

func doSome(v interface{}) {
  switch v := v.(type) {
  case *[]Color:
    *v = []Color{Color{0}, Color{128}, Color{255}}
  case *[]Brush:
    *v = []Brush{Brush{true}, Brush{true}, Brush{false}}
  default:
    panic("unsupported doSome input")
  }
}  

type Color struct {
    r uint8
}
type Brush struct {
    round bool
}

func main(){
    var c []Color
    doSome(&c) // after с is array contains 3 elements type Color

    var b []Brush
    doSome(&b) // after b is array contains 3 elements type Brush

    fmt.Println(b)
    fmt.Println(c)

}
3
Plato 7 Сен 2016 в 07:59