В приведенном выше примере вы определили u как тип User, но не указатель на пользователя. Поэтому вам нужно & u, потому что функция Decode в пакете json ожидает адрес или указатель.
Если вы создали экземпляр пользователя следующим образом: u: = new (Пользователь), это будет указатель, поскольку новая функция возвращает указатель. Вы также можете создать указатель на пользователя следующим образом: var u * User. Если вы сделали это, вам придется вытащить & в призыв к декодированию, чтобы он работал.
Указатели - это в основном переменные, которые содержат адреса. Когда вы ставите & перед переменной, он возвращает адрес. * Можно прочитать как «перенаправление». Поэтому, когда вы создаете указатель, как это:
вар х * INT
Это может быть прочитана как х будет перенаправлять на междунар. И когда вы присваиваете значение х вы могли бы дать ему адрес, как это: у: = 10 х = & у
где у какой-то Int. Поэтому, если вы хотите распечатать x, вы получите адрес y, но если вы распечатаете * x, вы перенаправите на то, что x указывает на значение y, которое равно 10. Если вы должны были распечатать & x, вы получите адрес указателя, x, сам.
Если вы попытались распечатать * y, который является просто int, а не указателем, это вызовет ошибку, потому что вы будете перенаправлять с некоторым значением, которое не является адресом для перенаправления.
Запуск ниже некоторый указатель удовольствия:
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!")
}
}
Надеется, что это помогает!
Логически оба они служат цели.Подумайте об этом так: когда вы передаете & n в функцию, вы передаете копию адреса памяти n - эквивалентную указателю. Если вы передаете * n в функцию, функция получает копию своих значений, которая является адресом памяти n. Так что в этом случае они не все так разные ... кроме, может быть, звездочки выглядят лучше :) – Snowman
@Snowman: ваш комментарий очень запутан. Вы не можете сказать, что они «не все так разные», когда они выполняют функционально противоположные вещи. Оператор '&' _references_ (принимает адрес значения) и '*' operator _dereferences_ (принимает значение по адресу). – JimB
@JimB Я просто указываю, что в контексте удовлетворения аргументов в вызове функции они не такие разные. В других контекстах они представляют собой два противоположных конца спектра. Является ли какой-либо из того, что я сказал неправильно? – Snowman