Я читал о том, как Go передает аргументы в функции через указатель или значение. Я читал о типе интерфейса. И я вмешивался в пакет отражений. Но ясно, я все еще не понимаю, как все это работает из-за этого примера кода здесь:
package main
import (
"reflect"
"fmt"
)
type Business struct {
Name string
}
func DoSomething(b []Business) {
var i interface{}
i = &b
v := reflect.ValueOf(i).Elem()
for c:=0 ;c<10; c++ {
z := reflect.New(v.Type().Elem())
s := reflect.ValueOf(z.Interface()).Elem()
s.Field(0).SetString("Pizza Store "+ fmt.Sprintf("%v",c))
v.Set(reflect.Append(v, z.Elem()))
}
fmt.Println(b)
}
func main() {
business := []Business{}
DoSomething(business)
}
Когда я запускаю этот код, он напечатает список из десяти бизнес-структур с Business.Name of Pizza от 0 до 9. Я понимаю, что в моем примере моя функция DoSomething
получила копию бизнес-фрагмента. и, следовательно, переменная business
в моей основной функции не зависит от того, что делает DoSomething
.
Затем я изменил func DoSomething(b []Business)
на func DoSomething(b interface{})
. Теперь, когда я пытаюсь запустить свой скрипт, я получаю ошибку времени выполнения panic: reflect: Elem of invalid type on
в строке z := reflect.New(v.Type().Elem())
Я заметил, что с DoSomething(b []Business)
переменная i == &[]
. Но с DoSomething(b interface{})
переменная i == 0xc42000e1d0
. Почему переменная i
отличается в этих двух обстоятельствах?