Swift 各版本特性

我们从3.0开始,之前的不考虑啦。

一、swift 3.0

1.新的GCD和Core Graphics:不同于之前的c语言形式,更加面向对象。

2.NS前缀从老的Foundation类型中移除,并且将基础类型改为值类型。

这点影响还是很大的,既是形变、也是质变。

3.新增两个内联序列函数sequence

这两个函数会根据我们给出的初始值,在遍历时应用闭包并以懒加载的方式返回一个序列,我们可以对结果进行遍历,filter、map等操作。

func sequence(first: T, next: @escaping (T) -> T?) -> UnfoldFirstSequence
func sequence(state: State, next: @escaping (inout State) -> T?) -> UnfoldSequence

下面的一个例子是遍历小于100的所有2的次幂,看不懂的建议了解一下sequence协议。

for i in sequence(first: 1, next: {$0*2}){
    print(i);
    if (i>100) {break};
}

4.新增权限filepravite、open

顾名思义filepravite表示被修饰对象的作用范围在当前文件内(这里对象泛指类、结构体、方法、变量等),与pravite区别在于,pravite表示被修饰对象的作用范围在当前类中(在extension中也不可以,这点在swift4.0中有修改,后面再说)。

被open修饰的对象可以咋其他module被访问,这点与public一直,不同的是被open修饰的对象可以在其他module中被继承,在子类中可以重新,而public不行。

5.移除诸多弃用特性,比如++,--

原因在于++,--并不比+=、-=简介,并且风格偏c,不符合swift编程风格。

二、swift 4.0

1.extension可以访问pravite修饰的对象。

这是对3.0的进一步修改。可能是觉得pravite在自己的extension访问不了比较不方便。

2.类型和协议的组合类型

其实就是我们声明某个类遵循某种协议的时候可以用 (类&协议) 的形式,也就相当于是类型和协议的组合类型。例子如下:

protocol MyProtocol {}
class UIView{}
class SubView: UIView,MyProtocol {}
class Test{
    var delegate:(UIView&MyProtocol)?
}
var test = Test();
test.delegate = UIView();  //报错
test.delegate = SubView(); //正常

3. associatedType可以追加Where约束

associatedtype的作用是在协议中保证类型的一致性,也是协议中的泛型。
可以看一下swift4.0对sequence的定义,

protocol Sequence {
    associatedtype Element where Self.Element == Self.Iterator.Element
    // ...
}

意思是序列中的元素类型必须与迭代器中的类型相等。

4.新的KeyPath语法

struct Kid {
    var nickname: String = ""
    var age: Double = 0.0
    var friends: [Kid] = []
}

var ben = Kid(nickname: "Benji", age: 8, friends: [])

let name = ben[keyPath: \Kid.nickname]
ben[keyPath: \Kid.nickname] = "BigBen"

5.下标支持泛型

struct GenericDictionary{
    private var data:[Key:Value]
    init(data:[Key:Value]) {
        self.data = data
    }
    subscript(key:Key) -> T?{
        return data[key] as? T
    }
}
let dict = GenericDictionary(data: ["name":"xiaoming"])
let name:String? = dict["Name"]

上面的例子,我们创建了一个通用字典,key、Path都是泛型,上面我们演示了下标泛型的写法,当然正常的写法可这样。

subscript(key:Key) -> Value?{
        return data[key]
}

下标支持泛型,使编码更加灵活。

5.字符串增强

1.增强了对unicode的支持,计算count的时候表情或者特殊字符如:\u{E9}会按照一个单位计算。
2.字符处理速度更快,这点对于开发者来说没有影响。
3.去掉了character,string类型不再有character,相关属性方法可以直接调用。
4.提供了新的语法糖,可用..进行单侧取值。之前必须两侧有值

let value = "abcdefg"
let startSlicingIndex = value.index(value.startIndex, offsetBy: 3)
let substr = value[..

5.遵循collection协议,同时具有了集合的一些功能。这个改变还是很贴心的。
6.subString


image.png

如上如,swift中的字符串有一个指向Owning Obj的指针,Owning Obj是用来跟踪和管理字符串的。当我们生成字串的时候字串Owning Obj的指针仍然会指向原字符串的Owning Obj对象,这会导致原字符串释放了,但是原字符串的Owning Obj对象没有释放,造成内存上的浪费。

swift4中截取的字串会使subSequence类型,并不是String类型,在赋值给字符串的时候需要String()转义,这个过程会重新生成一个字符串,包括新的Owning Obj。

var value = "abcdefg"
let startSlicingIndex = value.index(value.startIndex, offsetBy: 3)
let substr = value[...startSlicingIndex]
value = String(substr) //如不强转,编译报错。

6.多行字符串字面量

以前换行都要用\n代替,否则编译报错,现在可以舒舒服服直接写啦。

三、swift 5.0

1.ABI(Application Binary Interfaces,应用二进制接口)稳定

关于这个问题,可以看这里。
反正对于我们开发者来说,swift runtime不用再打到包里面了,体积肯定小了。

2.Raw String

我们可以用#来包裹字符串。
由于之前""中如果有特殊字符必须要加\进行转义,比如我们定义一个字符如果句子里面有"双引号"就很尴尬

let qutoedString = "如果句子里面有\"双引号\"就很尴尬"

这里我们可以这么写

let qutoedString = #"如果句子里面有"双引号"就很尴尬"#

其实添加#就是告诉编译器多有的字符都是原来的意思不用考虑类似\(参数)的情况。

3.标准库新增result

result是一个枚举类型,实现如下:

public enum Result where Failure: Error {

    /// A success, storing a `Success` value.
    case success(Success)

    /// A failure, storing a `Failure` value.
    case failure(Failure)
    
    ...
}

我们可以看到没居中定义了两个泛型,其中faulure必须遵循Error协议,我觉得这里swift给了我们一个结果处理的标准范式,相比以前我们要先判断error是否为空,然后判断数据是否为空的形式,这种形式更加简洁明了,举个自动贩卖机的例子。

enum payError:Error{
    case MoneyNotEnough
    case GoodsNotEnough
}

class VendingMachine{
    var unitPrice = 10;
    var goods = ["apple","banana","orange"];
    var restMoney = 100;
    func buyTheGood(money:Int,good:String) -> Result{
        if money < unitPrice {return .failure(.MoneyNotEnough)}
        if !self.goods.contains(good) {return .failure(.GoodsNotEnough)}
        self.goods = self.goods.filter({$0 != good})
        return .success(good)
    }
}

var machine = VendingMachine()
var result = machine.buyTheGood(money: 10, good: "apple");
switch result {
case .failure(let error):
    switch error {
    case .GoodsNotEnough:
        break;
    case .MoneyNotEnough:
        break;
    }
case .success(let good):
    break
}

下面对结果的switch判断是不是很nice。

4.定义了Python和ruby等脚本语言互操作的动态可调用类型。

差不多就是这些了,swift还是在稳步发展,潜力无限啊。

你可能感兴趣的:(Swift 各版本特性)