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只能用于无参数的闭包,加参数会报如下错误
个人还是推荐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修饰符