美文网首页
[Swift开发者必备Tips] 溢出

[Swift开发者必备Tips] 溢出

作者: PetitBread | 来源:发表于2018-01-30 16:11 被阅读124次

    对于 Mac 开发,我们早已步入了 64 位时代,而对 iOS 来说,64 位的乐章才刚刚开始。在今后一段时间内,我们都需要面临同时为 32 位和 64 位的设备进行开发的局面。由于这个条件所导致的最直接的一个结果就是数字类型的区别。

    最简单的例子,在 Swift 中我们一般简单地使用 Int 来表示整数,在 iPhone 5 和以下的设备中,这个类型其实等同于 Int32,而在 64 位设备中表示的是 Int64 (这点和 Objective-C 中的 NSInteger 表现是完全一样的,事实上,在 Swift 中 NSInteger 只是一个 Int 的 typealias。这就意味着,我们在开发的时候必须考虑同样的代码在不同平台上的表现差异,比如下面的这段计算在 32 位设备上和 64 位设备上的表现就完全不同:

    class MyClass {
        var a: Int = 1
        func method() {
            a = a * 100000
            a = a * 100000
            a = a * 100000
            print(a)
        }
    }
    
    MyClass().method()
    
    // 64 位环境 (iPhone 5s 及以上)
    // 1,000,000,000,000,000
    
    // 32 位环境 (iPhone 5c 及以下)
    // 崩溃
    

    因为 32 位的 Int 的最大值为 2,147,483,647,这个方法的计算已经超过了 Int32 的最大值。和其他一些编程语言的处理不同的是,Swift 在溢出的时候选择了让程序直接崩溃而不是截掉超出的部分,这也是一种安全性的表现。

    另外,编译器其实已经足够智能,可以帮助我们在编译的时候就发现某些必然的错误。比如:

    func method() {
        var max = Int.max
        max = max + 1
    }
    

    这种常量运算在编译时就进行了,发现计算溢出后编译无法通过。

    在存在溢出可能性的地方,第一选择当然是使用更大空间的类型来表示,比如将原来的 Int32 显式地声明为 Int64。如果 64 位整数还无法满足需求的话,我们也可以考虑使用两个 Int64 来软件实现 Int128 (据我所知现在还没有面向消费领域的 128 位的电子设备) 的行为。

    最后,如果我们想要其他编程语言那样的对溢出处理温柔一些,不是让程序崩溃,而是简单地从高位截断的话,可以使用溢出处理的运算符,在 Swift 中,我们可以使用以下这五个带有 & 的操作符,这样 Swift 就会忽略掉溢出的错误:

    • 溢出加法 (&+)
    • 溢出减法 (&-)
    • 溢出乘法 (&*)
    • 溢出除法 (&/)
    • 溢出求模 (&%)
      这样处理的结果:
    var max = Int.max
    max = max &+ 1
    
    // 64 位系统下
    // max = -9,223,372,036,854,775,808
    

    相关文章

      网友评论

          本文标题:[Swift开发者必备Tips] 溢出

          本文链接:https://www.haomeiwen.com/subject/equczxtx.html