本文是一個系列浮驳,是函數(shù)式Swift的讀書筆記(其實是為了備忘)
1變量和引用
Swift有兩種初始化變量的方法搜囱,var和let绍赛。
var聲明的變量可以賦新的值。 let創(chuàng)建的變量不能被修改钾菊。
var x: Int = 1
let y: Int = 2
x=3 //可以
y=4 //被編譯器拒絕
使用 let 聲明的變量被稱為 不可變變量
使用 var 聲明的變量則被叫做 可變變量
2 值類型和引用類型
不可變性并不只存在于變量聲明中,Swift類型分為 值類型和引用類型侠畔。最經(jīng)典的例子分別是結(jié)構(gòu)體和類结缚。
struct PointStruct {
var x:Int
var y:Int
}
var structPoint = PointStruct(x: 1, y: 2)
var sameStructPoint = structPoint
sameStructPoint.x = 3
//sameStructPoint 等于 (x: 3, y: 2)损晤。然而 structPoint 仍然保持原始值
class PointClass {
var x: Int
var y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
var classPoint = PointClass(x: 1, y: 2)
var sameClassPoint = classPoint
sameClassPoint.x = 3
//給 sameClassPoint.x 賦值將會修改 sameClassPoint 變量所指向的那個對象软棺,因為類是引用類型
//當(dāng)把一個值類型賦值給新的變量,或者傳遞給函數(shù)時尤勋,值類型總是會被復(fù)制喘落,而引用類型并不會被復(fù)制。對引用類型的對象來說最冰,只有對于對象的引用會被復(fù)制瘦棋,而不是對象本身
結(jié)構(gòu)體也提供了 mutating 方法,它們只能在被聲明為 var 的結(jié)構(gòu)體變量上被調(diào)用(此時結(jié)構(gòu)體內(nèi)的變量也需要時var)
extension PointStruct{
mutating func setStructToOrigin(){
x = 0
y = 0
}
}
//一個 mutating 方法只作用于單一變量暖哨,完全不影響其它變量
var myPoint = PointStruct(x: 100, y: 100)
let otherPoint = myPoint
myPoint.setStructToOrigin()
otherPoint // PointStruct(x: 100, y: 100)
myPoint // PointStruct(x: 0, y: 0)
3.結(jié)構(gòu)體和類赌朋,是否可變
對于結(jié)構(gòu)體類型:如果結(jié)構(gòu)體內(nèi)的變量使用了var, 而結(jié)構(gòu)體變量使用的是let篇裁。那么結(jié)構(gòu)體內(nèi)的變量也不能被修改沛慢。
let struct{
var x :Int
var y:Int
}
//此時 結(jié)構(gòu)體內(nèi)的x和y不能改變。
對于結(jié)構(gòu)體類型:如果結(jié)構(gòu)體內(nèi)變量使用的是let达布,結(jié)構(gòu)體變量使用的是var团甲,那么結(jié)構(gòu)體變量可以被修改。
var struct{
let x :Int
let y:Int
}
//此時 結(jié)構(gòu)體內(nèi)的x和y不能改變黍聂。 結(jié)構(gòu)體變量可以改變躺苦。
4. 討論
面向?qū)ο蟮恼Z言中,對于方法而言产还,由于共享實例變量而產(chǎn)生耦合的情況十分常見匹厘。其結(jié)果就是,修改變量的同時可能會改變類中方法的行為
引用透明函數(shù):不依賴外部變量脐区,也不改變外部變量集乔。引用透明性是模塊化和可重用性的重要保證。
Swift更傾向于使用let坡椒。它降低了程序的復(fù)雜性扰路,使得編寫引用透明函數(shù)更加容易。
在Swift中倔叼,我們一般不會徹底避免使用可變狀態(tài)汗唱。在不少情況下,函數(shù)會在其內(nèi)部使用一些可變狀態(tài)丈攒。比如如下例子
func sum(integers: [Int]) -> Int {
var result = 0
for x in integers {
result += x
}
return result //result是可變的哩罪。但是不會暴露給用戶的接口授霸。
}