《Swifter Tips》 读书笔记(1)

1.要习惯将protocol的一些方法声明为mutating,因为swift中的协议不仅可以用在class,struct和enum也是可以实现协议的,但是由于struct和enum是值类型,在内部对属性的更改有可能会影响到整体的值,如果此方法会改变属性值,就必须声明为mutating;而对于class则不是必须的,因为class本来就可以随意修改成员变量

protocol CircleChangeProtocol {
    mutating func toBigger(r: Int)
}

struct Circle : CircleChangeProtocol {
    var radius = 0
    mutating func toBigger(r: Int) {
        radius += r
    }
}

2.@autoclosure 做的事情就是把一句表达式自动地封装成一个闭包(closure)

func isTrue(checkIsTrue: () -> Bool) {
    if checkIsTrue() {
        print("true")
    } else {
        print("false")
    }
}

isTrue { () -> Bool in
    return 1 > 2
}

这是没有加@autoclosure一般写法,还可以简化成

isTrue { 1 > 2 }

加了@autoclosure后

isTrue(1 > 2)

Swift 将会把1>2 这个表达式⾃动转换为 () -> Bool
不过,@autoclosure只能用于无参数的闭包,加参数会报如下错误

1.png

个人还是推荐isTrue { 1 > 2 }的写法,直接isTrue(1 > 2)人家还以为isTrue的参数是传入一个Bool值呢

不过,苹果搞这个特性肯定不是为了写出难以理解的代码的,swift里有一个很方便的操作符“??”,例如

var width: Int?
let rectWidth = width ?? 200  //200

??可以方便的对optional类型进行判断,如果为nil,则执行??后面的闭包,返回同类型的值,

@autoclosure defaultValue:() -> T

这个就是@autoclosure的大功劳了,把闭包 { return 200 } 简化成 200
这里很像JavaScript、C#中的操作,JavaScript的函数中经常要对参数进行判断,如果参数为空,则设置默认值,不过操作符则是“||”,如

function buildRect(optionParam) {
    optionParam.width = optionParam.width || 100
    optionParam.height = optionParam.height || 200
    //...
}
buildRect()                            //width: 100, height: 200
buildRect({width: 300})                //width: 300, height: 200
buildRect({height: 200})               //width: 100, height: 200
buildRect({width: 300, height: 500})   //width: 300, height: 500

3.使Optional Chaining 所得到的东西其实都是Optional 的

4.操作符重载

struct Bag {
    var money = 200
}

func +(left: Bag, right: Bag) -> Bag {
    return Bag(money: left.money + right.money)
}

let aBag = Bag(money: 100)
let bBag = Bag(money: 200)

let cBag = aBag + bBag

cBag.money  // 300

5.在函数参数上,默认的参数修饰符是let,可以手动设置为var,但是swift2.2以后会有警告,不推荐这种写法,如果确实要在函数内部修改参数的值,使用inout修饰符

推荐阅读更多精彩内容