Ответ 1
В приведенном выше примере вы определили u как тип User, но не указатель на User. Так что вам нужен & u, потому что функция Decode в пакете json ожидает адрес или указатель.
Если вы создали экземпляр User следующим образом: u: = new (User), это был бы указатель, поскольку новая функция возвращает указатель. Вы также можете создать указатель на пользователя следующим образом: var u * User. Если бы вы сделали один из них, вам нужно было бы отключить &
в вызове Decode, чтобы он заработал.
Указатели - это в основном переменные, которые содержат адреса. Когда вы помещаете & перед переменной, она возвращает адрес. * Можно прочитать как "перенаправление". Итак, когда вы создаете указатель, как это:
var x * int
Это можно прочитать, так как x перенаправит на int. И когда вы присваиваете значение x, вы присваиваете ему такой адрес: y: = 10 x = & y
Где у какой-то инт. Таким образом, если бы вы распечатали x, вы бы получили адрес y, но если вы распечатали * x, вы перенаправили бы на то, на что указывает x, значение y равно 10. Если вы должны были распечатать & x, вы получит адрес указателя, х, сам.
Если вы попытаетесь распечатать * y, который является просто целым числом, а не указателем, он выдаст ошибку, потому что вы будете перенаправлять с некоторым значением, которое не является адресом для перенаправления.
Запустите ниже для некоторого веселья указатель:
package main
import "fmt"
func main() {
var y int
var pointerToY *int
var pointerToPointerToInt **int
y = 10
pointerToY = &y
pointerToPointerToInt = &pointerToY
fmt.Println("y: ", y)
fmt.Println("pointerToY: ", pointerToY)
fmt.Println("pointerToPointerToInt: ", pointerToPointerToInt)
fmt.Println("&y: ", &y) // address of y
fmt.Println("&pointerToY: ", &pointerToY)// address of pointerToY
fmt.Println("&pointerToPointerToInt: ", &pointerToPointerToInt) // address of pointerToPointerToInt
// fmt.Println(*y) throws an error because
// you can't redirect without an address..
// y only has int value of 10
fmt.Println("*pointerToY: ", *pointerToY) // gives the value of y
fmt.Println("*pointerToPointerToInt: ", *pointerToPointerToInt) // gives the value of pointerToY which is the address of y
fmt.Println("**pointerToPointerToInt: ", **pointerToPointerToInt) // this gives 10, because we are redirecting twice to get y
if pointerToY == *pointerToPointerToInt {
fmt.Println("'pointerToY == *pointerToPointerToInt' are the same!")
}
if pointerToY == &y {
fmt.Println("'pointerToY == &y' are the same!")
}
if &pointerToY == pointerToPointerToInt {
fmt.Println("'&pointerToY == pointerToPointerToInt' are the same!")
}
if y == **pointerToPointerToInt {
fmt.Println("'y == **pointerToPointerToInt' are the same!")
}
if pointerToY == *pointerToPointerToInt {
fmt.Println("'pointerToY == *pointerToPointerToInt' are the same!")
}
}
Надеюсь это поможет!