1

だから私はこれらの2つの記事とこの答えを読んでいます

[]string を []interface に変換できません {}は、メモリ レイアウトを変更する必要があることを示しています。

http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-goは、根底にあるメモリを理解することでこの質問に簡単に答えられると述べています。

http://research.swtch.com/interfacesは、内部で何が起こっているかを説明しています。

しかし、私の人生では、 []T を [] インターフェイスにキャストできない理由について、インターフェイスの実装に関して、理由を考えることができません。

なぜ?

4

2 に答える 2

4

記事「InterfaceSlice」で詳しく説明しています。

型を持つ変数[]interface{}はインターフェイスではありません! たまたま要素型が であるスライスですinterface{}。しかし、それを踏まえても、その意味は明らかであると言えます。

そうですね?型を持つ変数に[]interface{}は、コンパイル時に認識される特定のメモリ レイアウトがあります。

それぞれinterface{}が 2 つの単語を使用します (1 つの単語は含まれているものの型を表し、もう 1 つの単語は含まれているデータまたはそれへのポインターのいずれかを表します)。結果として、長さが N で type のスライスは、長さ[]interface{}が N*2 ワードのデータのチャンクによってサポートされます。

「 golangでの意味はinterface{}? 」も参照してください。

2ワード

[]MyTypeこれは、タイプと同じ長さのスライスを裏付けるデータのチャンクとは異なります。そのデータのチャンクはN*sizeof(MyType)ワード長になります。

[]MyTypeその結果、 typeの何かを type の何かにすばやく割り当てることができなくなり[]interface{}ます。それらの背後にあるデータは異なって見えるだけです。

Goで変換できない理由[]string[]interface{}」は、良い例を追加します。

// imagine this is possible
var sliceOfInterface = []interface{}(sliceOfStrings)
// since it's array of interface{} now - we can do anything
// let's put integer into the first position
sliceOfInterface[0] = 1
// sliceOfStrings still points to the same array, and now "one" is replaced by 1
fmt.Println(strings.ToUpper(sliceOfStrings[0])) // BANG!
于 2015-03-13T06:53:59.607 に答える
1

ブログ記事「The Laws of Reflection」のセクション「インターフェースの表現」を読んでください。

インターフェイス型の変数には、変数に割り当てられた具体的な値とその値の型記述子のペアが格納されます。より正確には、値はインターフェイスを実装する基礎となる具体的なデータ項目であり、型はその項目の完全な型を表します。

したがって、 がインターフェースではない[]T(のスライスT)の値がある場合T、そのようなスライスの要素は type の値のみを格納しますがT、型情報は格納せず、スライス タイプに属します。

type の値がある場合[]inteface{}、そのようなスライスの要素は具体的な値それらの値の型記述子を保持します。

したがって、 の要素は[]interface{}、非インターフェースよりも多くの情報 (より多くのメモリ) を必要とします[]T。また、これらの 2 つのスライスの占有メモリが同じでない場合、それらを別の方法で「見る」ことはできません (別のタイプとして見る)。一方を他方から生成するには、追加の作業が必要です。

于 2015-03-13T06:55:29.090 に答える