Это два разных случая:
Case1
num
- это указатель на int, поэтому вам нужно добавить целочисленное значение к значению, хранящемуся вадрес, указанный num
.Следовательно, вы разыменовываете указатель num
, чтобы получить значение, хранящееся в нем как:
func TestTest(num *int) {
*num = *num + 2 // dereference the pointer to get the value.
}
Case2
вы присваиваете строковое значение полю Color изApple, структура, которая не является указателем.Но вы используете указатель на структуру, а не на поле.Вот почему вы можете присвоить значение следующим образом:
func Eat(a *Apple) { // a is the pointer to struct.
a.Color = "green"
}
Теперь, если вы хотите сгенерировать ту же ошибку, что и в первом случае, создайте поле структуры типа указателя внутри структуры как:
type Apple struct {
Color *string // this is the pointer value which will throw the same error in your current implementation.
}
Код ошибки на Перейти на игровую площадку при попытке присвоить значение типа указателя переменной без указателя при использовании struct.
Решение
Чтобы установить значение, если вы используете поле указателя в структуре, используйте отражение как:
package main
import (
"fmt"
"reflect"
)
//I have my sample code like this.
type Apple struct {
Color *string
}
//In this way, the code runs just fine.
func main() {
var test = 6
TestTest(&test)
fmt.Println(test)
point := "red"
a := Apple{&point}
Eat(&a)
fmt.Println(a.Color)
}
func TestTest(num *int) {
*num = *num + 2
}
func Eat(a *Apple) {
str := "green"
r := reflect.ValueOf(a)
elm := r.Elem().FieldByName("Color")
elm.Set(reflect.ValueOf(&str))
fmt.Printf("%+v", (*a).Color)
}
Детская площадка Пример
Еще одинСледует отметить, что значение отражения на самом деле reflect.Ptr
, поэтому мы можем перебрать поля структуры, чтобы получить значение, а затем использовать reflect.Indirect
, чтобы получить значение цветового поля указателя типа.
func Eat(a *Apple) {
str := "green"
r := reflect.ValueOf(a).Elem()
elm := r.FieldByName("Color")
elm.Set(reflect.ValueOf(&str))
fmt.Printf("%+v\n", (*a).Color)
for i := 0; i < r.NumField(); i++ {
valueField := r.Field(i)
fmt.Println(reflect.Indirect(valueField))
}
// or use FieldByName to get the value of a field.
st := "Color"
fmt.Println(reflect.Indirect(reflect.ValueOf(a).Elem().FieldByName(st)))
}