https://tyablog.net/2020/01/05/difference-between-interface-and-pointer-in-golang/
Go言語ではインターフェイスとポインタの違いについて ちゃんと理解しておく必要があります。
C/C++を勉強した人にとってはポインタは理解できていると思いますが、Go言語にはインターフェイスというものも登場します。
C++でももちろん、interfaceというのは出てきますが、 C++の印象とはちょっと違ったものになっています。
Go言語がちょっとだけ違うのは、 インターフェイス値というものがあることです。
Goのインターフェイスは、実際には型情報と値情報の2つをもった構造体になっています。 その構造体に、型情報と値情報を動的に代入して扱っているのです。
ポインタは、値のメモリ空間を指し示す番地。
ポインタは、 プログラム実行時にメモリ空間を指し示す数字(番地)しか持ちません。
i1 := 123
fmt.Printf("%p\\n", &i1)
// ==> 0xc00009a728
i2 := 456
fmt.Printf("%p\\n", &i2)
// ==> 0xc00009a730
型情報自体はソースコード中の宣言で網羅されている為、 コンパイラは、コンパイル時にコード中の型情報をもとにポインタが適切な扱い方をされているのかチェックします。 そのため、プログラム実行時には実データの番地さえわかればいいというわけです。
次に示すのは、ポインタはコンパイル時に型チェックされていることを確認する例です。
// intのポインタであると宣言している
var ptr *int
// 型情報が合っているのでもちろんOK
intValue := 123
ptr = &intValue
// コンパイル時に型情報が違うことがわかるのでエラーにしてくれる
strValue := "hoge"
ptr = &strValue
cannot use &strValue (type string) as type int in assignment