iPerson
以下のコード スニペットでは、コンテンツがまだ初期化されていないときに正確に格納されるものを理解したいと思います: 0 バイトの値だけですか? それとも、実際にはボンネットの下のポインターですか (もちろん、0 バイトに初期化されています)? いずれにせよ、で正確に何が起こるのiPerson = person
ですか?
iPerson = person
のコピーを作成する場合person
、実装しているがサイズ/メモリ フットプリントが異なるオブジェクトIPerson
が に割り当てられるとどうなりiPerson
ますか? iPerson
はスタックに格納される変数であることを理解しているため、そのサイズは固定する必要があります。つまり、ヒープは実際には内部で使用されているため、iPerson
実際にはポインターとして実装されていますが、上記のコードで示されているように、割り当てはオブジェクトをコピーしますか? コードは次のとおりです。
type Person struct{ name string }
type IPerson interface{}
func main() {
var person Person = Person{"John"}
var iPerson IPerson
fmt.Println(person) // => John
fmt.Println(iPerson) // => <nil> ...so looks like a pointer
iPerson = person // ...this seems to be making a copy
fmt.Println(iPerson) // => John
person.name = "Mike"
fmt.Println(person) // => Mike
fmt.Println(iPerson) // => John ...so looks like it wasn't a pointer,
// or at least something was definitely copied
}
(この質問は、なぜ io.WriterString で実行時エラーが発生するのかに対する私の回答の正確な事実の正確性について考え直した結果です。そのため、インターフェース変数と割り当てが正確にどのようになっているのかを理解するために、いくつかの調査を試みることにしました。それらは Go で動作します。)
編集:いくつかの有用な回答を受け取った後、私はまだこれに戸惑っています:
iPerson = person
iPerson = &person
— どちらも合法です。しかし、私には、なぜコンパイラがそのような弱い型付けを許してしまうのかという疑問が生じます。上記の 1 つの意味は次のとおりです。
iPerson = &person
var person2 = iPerson.(Person) # panic: interface conversion: interface is *main.Person, not main.Person
一方、最初の行を変更すると修正されます。
iPerson = person
var person2 = iPerson.(Person) # OK
iPerson
...したがって、ポインタまたは値のどちらを保持しているかを静的に判断することはできません。エラーが発生することなく、実行時にどちらかを割り当てることができるようです。なぜそのような設計決定が下されたのですか?それはどのような目的に役立ちますか?「タイプセーフ」の考え方には絶対に適合しません。