go界面中也有一些类似的设计。例如,读取和写入的结果只能是 values >= 0。为什么不直接使用unsigned int类型?使用签名类型的目的是什么?
// The Copy function uses ReaderFrom if available.
type ReaderFrom interface {
ReadFrom(r Reader) (n int64, err error)
}
// The Copy function uses WriterTo if available.
type WriterTo interface {
WriteTo(w Writer) (n int64, err error)
}
Run Code Online (Sandbox Code Playgroud)
我在Go Programming Language (A. Donovan, B. Kernighan)一书中找到了一个很好的解释:
尽管 Go 提供了无符号数和算术,但我们倾向于使用有符号
int形式,即使对于不能为负的数量,例如数组的长度,尽管uint这似乎是一个更明显的选择。事实上,内置len函数返回一个 signedint,就像在这个循环中以相反的顺序宣布奖牌:
medals := []string{"gold", "silver", "bronze"}
for i := len(medals) - 1; i >= 0; i-- {
fmt.Println(medals[i]) // "bronze", "silver", "gold"
}
Run Code Online (Sandbox Code Playgroud)
替代方案将是灾难性的。如果
len返回一个无符号数,那么i也将是 auint,并且条件i >= 0根据定义始终为真。在第三次迭代之后,其中i == 0,i--语句将导致i不是 ?1,而是最大值uint,并且medals[i]由于尝试访问切片边界之外的元素, 的评估将在运行时失败或恐慌。出于这个原因,无符号数往往仅在需要按位运算符或特殊算术运算符时才使用,例如在实现位集、解析二进制文件时。