3

我有

type DocId int

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

如何摆脱显式转换线?DocIds旨在成为索引单个文档的类型。

我想要的更像是:

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

当我尝试将范围中的 id 用作 DocId 时,即使 DocId 是一个 int,这给了我“无效操作:...(不匹配的类型 int 和 DocId)”。

4

2 回答 2

4

只有无类型的常量才能自动转换为正确的类型。

您可以在此线程中找到不需要强制转换的示例,用于无类型常量。从规格

如果一个操作数是无类型常量而另一个操作数不是,则将常量转换为另一个操作数的类型

但是在这里,range将迭代值显式分配给相应的迭代变量(i int, T a[i]),这使得iint。(来自规范“ For statement ”)

对于所有其他情况,需要显式强制转换。
规范的“转换”部分没有提到“自动”类型转换(与自动接口转换相反,它一直在发生:)interface{}

该线程添加

type A int
type B int

...

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

本质上,由于(几乎)所有类型都是唯一的,因此即使是具有相同底层表示和原始操作的两种类型,如果没有强制转换也是无法分配的。[...]
这通过强制您明确告诉编译器何时希望进行转换来使语言类型安全。

于 2012-10-05T12:14:35.650 回答
3

这是您可能喜欢也可能不喜欢的另一个想法 - 使用 amap因为地图可以具有与切片不同的自定义类型的键。

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 回答