Types 为什么Swift语言指南建议使用Int;即使已知值为非负“时,也不例外;?

Types 为什么Swift语言指南建议使用Int;即使已知值为非负“时,也不例外;?,types,coding-style,swift,type-safety,Types,Coding Style,Swift,Type Safety,这是一个关于Swift编程风格的问题,特别是IntvsUInt Swift编程语言指南建议程序员使用通用的有符号整数类型Int,即使已知变量为非负。发件人: 仅当您特别需要与平台本机字大小相同大小的无符号整数类型时,才使用UInt。如果不是这种情况,则最好使用Int,即使要存储的值已知为非负。对整数值一致使用Int有助于代码互操作性,避免在不同的数字类型之间转换,并匹配整数类型推断,如类型安全和类型推断中所述 但是,UInt在32位体系结构上是32位无符号的,在64位体系结构上是64位无符号的,

这是一个关于Swift编程风格的问题,特别是
Int
vs
UInt

Swift编程语言指南建议程序员使用通用的有符号整数类型
Int
,即使已知变量为非负。发件人:

仅当您特别需要与平台本机字大小相同大小的无符号整数类型时,才使用UInt。如果不是这种情况,则最好使用Int,即使要存储的值已知为非负。对整数值一致使用Int有助于代码互操作性,避免在不同的数字类型之间转换,并匹配整数类型推断,如类型安全和类型推断中所述

但是,
UInt
在32位体系结构上是32位无符号的,在64位体系结构上是64位无符号的,因此在
UInt
上使用
Int
对性能没有好处

相比之下,Swift指南给出了后面的示例:

让年龄=-3
断言(年龄>=0,“一个人的年龄不能小于零”)
//这会导致触发断言,因为年龄不大于等于0

在这里,如果代码编写为:

let age:UInt = -3  
// this causes a compiler error because -3 is negative
在许多其他情况下(例如,对集合进行索引的任何内容),使用
UInt
将在编译时而不是运行时捕获问题

所以问题是:Swift编程语言指南中的建议是否合理,使用
Int
“即使已知要存储的值为非负”的好处是否超过了使用
UInt
的安全好处

补充说明:使用Swift已有几周,现在很明显,要与Cocoa
UInt
实现互操作性,需要使用Swift。例如,
AVFoundation
框架在任何需要“计数”(采样数/帧数/通道数等)的地方使用无符号整数。将这些值转换为
Int
可能会导致严重的错误,其中值大于您在问题中提到的
Int.max

。。 整型值一致使用Int有助于代码的互操作性,避免在不同的数字类型之间转换,并匹配整型推断,如类型安全和类型推断中所述

这样可以避免将Int赋值给UInt等问题。分配给UINT的负Int值会导致较大的值,而不是预期的负值。二者的二进制表示并不能区分一种类型和另一种类型

而且,这两个类都是类,一个不是另一个的后代。在不重载的情况下,生成receive Int的类无法接收UINT,这意味着在大多数框架接收Int时,在这两个类之间进行转换将是UINT的常见任务。在两者之间转换也可以成为一项非繁琐的任务


前面两段提到“互操作性”和“不同数字类型之间的转换”。如果不使用UInt可以避免的问题。

我认为使用UInt并不像您认为的那样安全。正如你所指出的:

let age:UInt = -3
导致编译器错误。我还尝试:

let myAge:Int = 1
let age:UInt = UInt(myAge) - 3
这也导致了一个编译器错误。然而,以下(我认为在实际程序中更常见)场景没有编译器错误,但实际上导致了
EXC\u BAD\u指令的运行时错误

func sub10(num: Int) -> UInt {
    return UInt(num - 10) //Runtime error when num < 10
}
sub10(4)
如果这些是普通的
Int
s,您可以添加代码来检查您的条件,而不是崩溃:

if a.aboveZero > 0 {
    //Do your thing
} else {
    //Handle bad data
}

我甚至可能会将他们反对使用
UInt
s的建议等同于他们反对使用隐式未包装选项的建议:除非你确定不会有任何负面影响,否则不要这样做,否则你会出现运行时错误(最简单的情况除外)。

对,因此,这实际上是关于与Swift框架的互操作性。我仍然认为,一般来说,对已知的非负值使用无符号整数更安全,但我同意,对于每种类型的所有可能值,这两种类型之间没有合理的转换。因此,如果互操作性优于安全性,那么我理解在可能的情况下使用INT的设计选择。当然这取决于您认为重要的是什么。我倾向于同意文档,它只是使代码更易于使用
int
@JackJames。我同意这是单个开发人员的优先级问题和正在处理的代码。我没有看到一个令人信服的例子,这让我认为苹果不应该建议人们不要使用UInt,因为严格使用Int可能会导致代码以各种恶劣的方式中断。传统上不鼓励使用C中的无符号整数的原因是,倒计数
for
循环很容易出错;e、 g.
for(未签名的a=10;a>0;--a)
是错误的,因为
a
根据定义总是>0。同意杰克和杰米的观点。对已知的非负值使用UInt将意向和语义信息传达给下一个阅读代码的开发人员。如果您将互操作性置于此之上,则可以选择Int。@alastair
未签名的a
并不总是>0,而是>=0您可以同样轻松地为
UInt
案例添加这些检查;您只需要检查
num
a.overzero
是否
>=10
。此外,您还可以使用num&-10禁用运行时溢出检查。
if a.aboveZero > 0 {
    //Do your thing
} else {
    //Handle bad data
}