【问题标题】:Precondition failed: Negative count not allowed前提条件失败:不允许负数
【发布时间】:2018-08-24 23:56:41
【问题描述】:

错误:

Precondition failed: Negative count not allowed: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/StringLegacy.swift, line 49

代码:

String(repeating: "a", count: -1)

思考:

好吧,将某个字符串重复负数次是没有意义的。既然我们在 Swift 中有类型,为什么不使用 UInt

这里有一些关于它的文档。

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

Apple Docs

好吧,Int 是首选,因此 API 只是遵循规则,但为什么 Strings API 是这样设计的?为什么这个构造函数不是私有的,而带有UInt ro 的公共构造函数是这样的?有“真实”的原因吗?这是某种“未定义的行为”吗?

还有:https://forums.developer.apple.com/thread/98594

【问题讨论】:

    标签: swift string int repeat uint


    【解决方案1】:

    这不是未定义的行为——事实上,前提条件正好相反:进行了明确的检查以确保给定的count 是肯定的。

    至于为什么参数是 Int 而不是 UInt — 这是 Swift 设计早期做出的两个决定的结果:

    1. 与 C 和 Objective-C 不同,Swift 不允许在整数类型之间进行隐式(甚至显式)转换。您不能将Int 传递给采用UInt 的函数,反之亦然,以下转换也不会成功:myInt as? UInt。 Swift 首选的转换方法是使用初始化器:UInt(myInt)
    2. 由于Ints 比UInts 更普遍适用,它们将是首选的整数类型

    因此,由于在Ints 和UInts 之间进行转换可能既麻烦又冗长,因此在最大数量的 API 之间进行互操作的最简单方法是将它们全部写入通用整数货币类型:@ 987654332@。正如您引用的文档所提到的,这“有助于代码互操作性,避免在不同数字类型之间进行转换,并匹配整数类型推断”;在运行时捕获无效输入是此决定的折衷。

    事实上,Int 在 Swift 中是如此根深蒂固,以至于当 Apple 框架接口从 Objective-C 导入 Swift 时,NSUInteger 参数和返回类型被转换为 Int 而不是 UInt,对于显着更容易的互操作性。

    【讨论】:

    • 请注意,我的问题更具哲学性,因为我们在 Swift 中进行了所有这些类型安全的事情,我们可以防止这种情况发生,为什么他们故意使用 Int 创建构造函数?因此,Apple 只是不想在另一个带有 count: UIntString 构造函数中实现 UInt -> Int 转换,因为它们得到了这些设计决策的“支持”,即使这个(也许还有其他)API 变得“无意义”,因为我们没有负数的重复?感谢您的回复!
    • 并不是 Swift 开发人员不想实现 UIntInt 的转换,或者不能让 String 的初始化程序采用 UInt — 而是这种设计的结果让你,API 的使用者,不断地在IntUInt 之间进行转换,用funcThatTakesInt(Int(resultOfSomeOtherFuncThatReturnsUInt)) 乱扔代码并处理那里的所有潜在问题。
    • 请注意,有些语言,如 Java,根本没有无符号整数类型,它们处理得很好。 Swift 提供了无符号类型以实现 C 兼容性,以及您真正需要整数类型的全部范围或执行排序的位旋转的情况,但通用语是有符号整数类型;为了不给您带来负担,几乎所有 API 都采用 Int
    • 还要注意,这样做是为了避免 C/Objective-C 的隐式转换规则,这会导致很多现实世界的错误。摆脱隐式强制转换的唯一方法是显式强制转换,这让你,嗯,到处都是显式强制转换,这是一个很大的痛苦。这留下了像这样的边缘情况,是的,无符号类型会更有意义——但用Int 编写它的实用主义有时胜过UInt 的迂腐主义。 (我个人倾向于迂腐,但总会有我们不同意的 API 设计决策。):)
    猜你喜欢
    • 1970-01-01
    • 2018-08-12
    • 2016-11-28
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 2017-01-08
    • 1970-01-01
    相关资源
    最近更新 更多