【问题标题】:What's the rationale of Swift's size methods taking `Int`s?Swift 的 size 方法采用“Int”的基本原理是什么?
【发布时间】:2014-09-22 11:07:29
【问题描述】:

我注意到很多 swift 内置插件使用或返回 Ints 而不是 UInts:

这里有一些来自Array的例子:

mutating func reserveCapacity(minimumCapacity: Int)

var capacity: Int { get }

init(count: Int, repeatedValue: T)

mutating func removeAtIndex(index: Int) -> T

鉴于该语言是全新的,并且假设这种设计选择不是任意的 - 我想知道:为什么 swift 内置插件采用 Ints 而不是 UInts?

一些注意事项:问是因为我自己正在处理一些集合,我想知道我应该为reserveCapacity 等使用什么类型。我自然希望reserveCapacity 使用@改为 987654329@。

【问题讨论】:

    标签: swift


    【解决方案1】:

    UInt 是导致错误的常见原因。很容易意外生成 -1 并以无限循环或类似问题结束。 (许多 C 和 C++ 程序员都知道,除非需要 unsigned,否则你真的应该只使用 int。)由于 Swift 管理类型转换的方式,这一点更加重要。如果您曾经使用 NSUInteger 并打开“签名到无符号”警告(这是 Swift 中的错误,而不是像 C 中那样的可选警告),您就会知道那是多么痛苦。

    Swift 编程指南在UInt 部分解释了它们的具体原理:

    注意

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

    【讨论】:

    • 在 Swift 中,您描述的问题不是问题。您不能将带有负值的 int 作为 UInt 传递并对其进行类型转换。 (就像你说的,这是 Swift 中的一个错误)。
    • 没错。因此,您经常不得不使用UInt(x) + y 将其保存在UInt 空间中。例如,如果您创建一个常量,它将类型推断为Int,因此您必须强制转换它。如果您使用任何返回 Int 的东西(很多事情都会这样做),那么您将不得不强制转换它。施法变得非常过度,你不再关注施法是否真的安全;您不能总是将 int 转换为 unsigned,反之亦然。当您考虑到“while x
    • 这是从有类似问题的 C、ObjC 和 C++ 中吸取的教训。斯威夫特正试图避开这个常见的错误。有关在 Swift 的前辈中推荐相同行为的众多地方之一,请参阅 Google C++ 样式指南:google-styleguide.googlecode.com/svn/trunk/…“您不应该使用无符号整数类型,例如 uint32_t,除非有正当理由,例如表示位模式......特别是,不要使用无符号类型来表示一个数字永远不会是负数。相反,为此使用断言。”
    • Google 风格指南的链接已过时。这是新的:google.github.io/styleguide/cppguide.html#Integer_Types
    【解决方案2】:

    这是一个可能的解释(我不是这方面的专家):假设你有这个代码

    let x = 3
    test(x)
    
    func test(t: Int) {
    }
    

    这将毫无问题地编译,因为 'x' 的类型被推断为 Int。

    但是,如果你把函数改为

    func test(t: UInt) {
    }
    

    编译器会给你一个构建错误 ('Int' is not convertible to 'UInt')

    所以我的猜测是这只是为了方便,因为 Swift 的类型安全性会要求你每次都手动转换它们。

    【讨论】:

    • 对于它的价值that was my guess too,但这是一个相当疯狂的猜测,做let x:UInt = 3 可以解决它或test(UInt(x))。两者似乎都更加“Swiftic”
    • 好吧,我不同意 ;-) 我认为没有类型注释/转换它看起来更干净。
    • 特别是,UInt(x) 甚至可能都不可能。它可能会失败。每次使用时都需要考虑这一点。如果你使用x:UInt,那么如果你需要将它传递给使用Int 的东西,就会出现同样的问题。想象一下xscale 并可能适用于正面或负面的不常见情况,包括应该只是正面的事物。你进入一个触发器,在IntUInt 之间切换你的scale 常量,试图得到你想要的更频繁的那个(或者你创建两个 常量,它更丑)。
    • (顺便说一句,该示例来自我实际的 Swift 代码。我开始尝试使用 UInt 来表示“不能为负数”并很快了解到为什么这不是一个好主意,并且然后发现Apple也提到不要这样做。)
    猜你喜欢
    • 2013-05-28
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 2017-06-16
    • 1970-01-01
    相关资源
    最近更新 更多