3

私は持っています

type DocId int

func foo(documents []String) {
    for i := range documents {
        id := DocId(i)
        ...
    }
}

明示的な変換ラインを削除するにはどうすればよいですか?DocIdは、個々のドキュメントにインデックスを付けるタイプであることが意図されています。

私が欲しいのはもっと似ています:

func foo(documents []String) {
    for id := range documents {
        ... // id gets used as the DocId that it damn well *IS*
    }
}

DocIdがintであっても、範囲のIDをDocIdとして使用しようとすると、「無効な操作:...(intとDocIdの型が一致しません)」が発生します。

4

2 に答える 2

4

正しい型に自動的に変換できるのは、型指定されていない定数のみです。

このスレッドのように、型指定されていない定数の場合、キャストが不要な例を見つけることができます。仕様から:

一方のオペランドが型なし定数で、もう一方のオペランドがそうでない場合、定数はもう一方のオペランドの型に変換されます

しかし、ここではrange、対応する反復変数 に反復値を明示的に(i int, T a[i])割り当てiますint。(スペック「For ステートメント」より)

それ以外の場合は、明示的なキャストが必要です。
仕様の「変換」セクションでは、「自動」型変換について言及していません (常に発生する自動インターフェイス変換とは対照的に: interface{})。

このスレッドは追加します

type A int
type B int

...

var a A = 5
var b B = a    // Compiler ERROR!!!!!!

基本的に、(ほぼ) すべての型が一意であるため、基になる表現とプリミティブ操作が同じ 2 つの型であっても、キャストなしでは代入できません。[...]
これにより、変換を行うタイミングをコンパイラに明示的に伝えることを強制することで、言語をタイプ セーフにします。

于 2012-10-05T12:14:35.650 に答える
3

好き嫌いが分かれる別のアイデアを次に示しますmap。マップはスライスとは異なり、カスタム タイプのキーを持つことができるため、 a を使用します。

type DocId int

func foo(documents map[DocId]string) {
    for id := range documents {
        // do stuff with id and documents[id]
    }
}
于 2012-10-05T20:11:49.687 に答える