美文网首页
swift 3.1新特性

swift 3.1新特性

作者: SamuelSeed | 来源:发表于2017-03-28 16:46 被阅读77次

    好消息:Xcode 8.3和Swift3.1现在已经推出beta版啦!这次更新包含了许多期待已久的Swift包管理特性和语言自身的改进。

    如果你最近有关注Swift演化进程,读下去,这篇文章就是写给你的。
    在本文中,我会列出Swift3.1中最重要的对我们写代码有很大影响的改变。让我们开始吧。

    开始之前

    Swift3.1兼容3.0,所以如果你已经使用Xcode的 Edit\Convert\To Current Swift Syntax… 功能将你的项目迁移到Swift3.0,这些新特性不会破坏你的代码。但是,Apple已经放弃了Xcode8.3中对Swift2.3的支持.所以如果你的项目还没有从Swift2.3迁移过来的话,是时候做这件事啦。

    然后,打开Xcode,选择File\New\Playground…。选择iOS平台,随便起个名字,保存到某个地方。当你在读这篇文章时,在这个playground里尝试每一个新特性吧。

    语言层面的改进

    首先,让我们来先看一下这次更新中语言层面的改进,包括数字类型初始化失败,新的序列函数等等。

    数字类型转换提供失败时的初始化方法

    Swift3.1对所有的数字类型都提供了失败初始化方法(包括Int, Int8, Int16, Int32, Int64, UInt, UInt8, UInt16, UInt32, UInt64, Float, Float80, Double),该方法要么返回无损的转换信息,要么返回nil。

    这个特性可以用一种安全并且可以回收利用的方式处理一些附带额外信息的松散类型数据转换。比如,你可能会这样处理存放学生信息的JSON数组:

    class Student {
      let name: String
      let grade: Int
     
      init?(json: [String: Any]) {
        guard let name = json["name"] as? String,
              let gradeString = json["grade"] as? String,
              let gradeDouble = Double(gradeString),
              let grade = Int(exactly: gradeDouble)  // <-- 3.1 feature here
        else {
            return nil
        }
        self.name = name
        self.grade = grade
      }
    }
     
    func makeStudents(with data: Data) -> [Student] {
      guard let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments),
            let jsonArray = json as? [[String: Any]] else {
        return []
      }
      return jsonArray.flatMap(Student.init)
    }
     
    let rawStudents = "[{\"name\":\"Ray\", \"grade\":\"5.0\"}, {\"name\":\"Matt\", \"grade\":\"6\"},
                        {\"name\":\"Chris\", \"grade\":\"6.33\"}, {\"name\":\"Cosmin\", \"grade\":\"7\"}, 
                        {\"name\":\"Steven\", \"grade\":\"7.5\"}]"
    let data = rawStudents.data(using: .utf8)!
    let students = makeStudents(with: data)
    dump(students) // [(name: "Ray", grade: 5), (name: "Matt", grade: 6), (name: "Cosmin", grade: 7)]
    

    我们使用到了一个从Double转成Int的失败初始化方法来转换Student类失败初始化方法中的grade属性:

    let grade = Int(exactly: gradeDouble)
    

    如果gradeDouble是带小数点的,比如6.33,它就会失败。如果可以完全用一个Int代表,比如6.0,它就会成功。

    新的序列函数

    Swift3.1在标准库的Sequence协议中增加了两个新的函数来进行数据过滤:
    prefix(while:)drop(while:)

    来看这个斐波那契数列

    let fibonacci = sequence(state: (0, 1)) {
      (state: inout (Int, Int)) -> Int? in
      defer {state = (state.1, state.0 + state.1)}
      return state.0
    }
    

    在Swift3.0中你可以指定重复次数来获取数列中的值:

    // Swift 3.0
    for number in fibonacci.prefix(10) {
      print(number)  // 0 1 1 2 3 5 8 13 21 34
    }
    

    Swift3.1中你可以使用指定条件的prefix(while:)drop(while:)函数来获取在某个范围内的所有元素,像这样:

    // Swift 3.1
    let interval = fibonacci.prefix(while: {$0 < 1000}).drop(while: {$0 < 100})
    for element in interval {
      print(element) // 144 233 377 610 987
    }
    

    prefix(while:)返回满足特定断言的最大范围的子序列。它从序列的最头部开始在闭包第一次返回 false 的时候结束。

    与之相对,drop(while:)从闭包第一次返回false时开始,到序列的最尾部结束。

    Note:你可能想使用拖尾闭包语法在这种情况下:

    let interval = fibonacci.prefix{$0 < 1000}.drop{$0 < 100}
    

    未完待续...

    相关文章

      网友评论

          本文标题:swift 3.1新特性

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