前言
Swift作為一門新語言灯变,對于熟練掌握Objective-C編程的iOS開發(fā)者來說其實很容易上手,但其在語法和編程習慣上改變了很多赌厅,對于從未了解Objective-C語言而從Swift開始學習iOS開發(fā)的新手來說可能上手有一定難度,下面我將這段時間的學習成果結(jié)合官方文檔說明做一個簡單的匯總,希望可以幫助到正在學習Swift的小伙伴們杉辙。
本文主要是介紹Swift中最常用的常量和變量,將從常量和變量的 定義與申明捶朵、命名規(guī)范蜘矢、兩者的深入思考 三個方面入手,入門基礎篇综看,重點介紹變量和常量的使用以及區(qū)別品腹,希望大家在閱讀完本文后都可以熟練使用它們。
常量和變量的定義與申明
-
定義
Swift開發(fā)文檔中是這樣定義變量和常量的:
常量和變量把名字和一個特定類型的值關聯(lián)起來寓搬。常量的值一旦設置好便不能再被更改珍昨,然而變量可以在將來被設置為不同的值。
-
申明
常量和變量必須在使用前被聲明句喷,使用關鍵字 let 來聲明常量镣典,使用關鍵字 var 來聲明變量。舉個簡單的例子:
class Person: NSObject {
let life = 1
var age = 0
}
這里我們有一個Person類繼承NSObject唾琼,顯然人的生命只有一條應該設置為不可以改變的常量兄春,但是人的年齡是隨著時間變化的應該聲明為變量,同理锡溯,當你在開發(fā)過程中有類似需求時應該這樣來選擇何時使用變量赶舆、何時使用常量。
當然我們可以選擇一行代碼以逗號分隔的形式申明多個簡單的變量或常量如下所示:
var a = 0, b = 1.0, c = "CoderYQ"
-
Swift中的類型安全和類型推斷
Swift 是一門類型安全的語言祭饭,即你必須時刻清楚此時代碼需要處理的值的類型芜茵,編譯器會進行類型檢查,任何不匹配的類型都會被標記為錯誤當然更不能參與運算倡蝙。當你操作不同類型的值時九串,類型檢查能幫助你避免錯誤。當然并不是所有的變量和常量都需要明確指出一個確定的類型寺鸥,如果你沒有為申明的變量或常量指定類型猪钮,Swift 會使用類型推斷的功能推斷出合適的類型,通過檢查你給變量賦的值胆建,類型推斷能夠在編譯階段自動的推斷出值的類型烤低,這就是Swift中類型推斷。就像上面的連續(xù)申明變量
a
笆载、b
扑馁、c
的代碼中我們并沒有明確指出三者的類型涯呻,編譯器則是通過你給三者賦的值來推斷三者的類型分別為:Int
類型、Double
類型檐蚜、String
類型魄懂。
但是在某些必要時刻我們是需要給申明的變量或常量提供類型標注的,以此來明確他們能夠存儲的值闯第。添加類型標注的方法是在變量或常量的名字后邊加一個冒號市栗,再跟一個空格,最后加上要使用的類型名稱(這里和Objective-C中不太一樣)咳短,如下所示的代碼效果其實和上面的是一樣的:
var a: Int = 0
var b: Double = 1.0
var c: String = "CoderYQ"
如果變量的類型都一樣填帽,我們還可以這樣申明:
var a, b, c : Double
命名規(guī)范
常量和變量的名字幾乎可以使用任何字符,甚至包括 Unicode 字符:
let π = 3.14159
let 你好 = "你好世界"
let ???? = "dog cow"
官方文檔對于命名規(guī)范還有這樣的要求:
常量和變量的名字不能包含空白字符咙好、數(shù)學符號篡腌、箭頭、保留的(或者無效的)Unicode 碼位勾效、連線和制表符嘹悼。也不能以數(shù)字開頭,盡管數(shù)字幾乎可以使用在名字其他的任何地方层宫。
一旦你聲明了一個確定類型的常量或者變量杨伙,就不能使用相同的名字再次進行聲明,也不能讓它改存其他類型的值萌腿。常量和變量之間也不能互換限匣,如果你需要使用 Swift 保留的關鍵字來給常量或變量命名,可以使用反引號( ` )包圍它來作為名稱毁菱∶姿溃總之,除非別無選擇贮庞,避免使用關鍵字作為名字除非你確實別無選擇峦筒。
總結(jié)一句:Swift中變量和常量的命名相較于Objective-C中更加靈活多變,但是仍然有上面的規(guī)定需要注意窗慎,而且他們的命名盡量做到見名知意勘天,以便于開發(fā)人員之間的協(xié)同合作。這里我給大家列出了Swift中主要的關鍵字捉邢,希望大家在命名的時候盡量規(guī)避他們。
- 用作聲明的關鍵字:
class商膊、deinit伏伐、enum、extension晕拆、func藐翎、import材蹬、init、let吝镣、protocol堤器、static、struct末贾、subscript闸溃、typealias、var
- 用作語句的關鍵字:
break拱撵、case辉川、continue、default拴测、do乓旗、else、fallthrough集索、if屿愚、in、for务荆、return妆距、switch、where蛹含、while
- 用作表達和類型的關鍵字:
as毅厚、dynamicType、is浦箱、new吸耿、super、self酷窥、Self咽安、Type、__COLUMN__蓬推、__FILE__妆棒、__FUNCTION__、__LINE__
- 特定上下文中被保留的關鍵字:
associativity沸伏、didSet糕珊、get、infix毅糟、inout红选、left、mutating姆另、none喇肋、nonmutating坟乾、operator、override蝶防、postfix甚侣、precedence、prefix间学、right殷费、set、unowned菱鸥、unowned(safe)宗兼、unowned(unsafe)、weak氮采、willSet
深入思考
經(jīng)過上面的學習我們已經(jīng)能夠熟練使用常量和變量了殷绍,那么兩者之間在使用上到底有何區(qū)別呢?這里通過例子說明一下:
//通過 UIView() 方法創(chuàng)建一個 UIView 的對象
//(假設系統(tǒng)分配的內(nèi)存地址為:0x7faa31616bb0)并賦值給申明為 UIView類型 的常量:view0
let view0 : UIView = UIView()
//通過 UIView() 方法創(chuàng)建另外一個 UIView 的對象
//(假設系統(tǒng)分配的內(nèi)存地址為:0x7f9890c062b0) 并賦值給申明為 UIView類型 的變量:view1
var view1 : UIView = UIView()
第一行代碼的意思:首先在內(nèi)存中的堆區(qū)創(chuàng)建一個內(nèi)存地址為
0x7faa31616bb0
的UIView
類型的對象鹊漠,然后在內(nèi)存中的棧區(qū)申明一個名為view0
的常量指向該對象主到,即view0
中保存的是0x7faa31616bb0
這個地址,而且該常量的值是不可變的(這不廢話嗎)躯概,即view0
中保存的內(nèi)存地址不能變了登钥。第二行代碼的意思: 在堆區(qū)又創(chuàng)建一個新的內(nèi)存地址為
0x7f9890c062b0
的UIView
類型的對象,然后在棧區(qū)又申明一個名為view1
的變量指向該對象娶靡,即view0
中保存的是0x7faa31616bb0
這個地址牧牢,注意此時view1
的值是可以改變的,即view1
中保存的內(nèi)存地址是可以變化的姿锭。
如果此時執(zhí)行下面的操作:
//重新創(chuàng)建一個新的 `UIView` 的對象
//(假設系統(tǒng)分配的內(nèi)存地址為:`0x7f9890c042b0`)并賦值給上面的常量 `view0`
view0 = UIView()
編譯器會報這樣的錯誤:
error: cannot assign to value: 'view0' is a 'let' constant,
change 'let' to 'var' to make it mutable
錯誤原因:創(chuàng)建一個新的對象有一個新的內(nèi)存地址塔鳍,你把新的對象重新賦值給view0
,即view0
現(xiàn)在指向另一個對象了呻此,相當于將view0
中的原來存儲的0x7faa31616bb0
內(nèi)存地址修改成了0x7f9890c042b0
轮纫,但是view0
中存儲的內(nèi)存地址一旦賦值了是不能修改的,所以編譯器這里就報錯了焚鲜,他建議你將 let 變成 var 來申明 view0
掌唾。
//重新創(chuàng)建一個新的 `UIView` 的對象
//(假設系統(tǒng)分配的內(nèi)存地址為:`0x7f9890c042b0`)并賦值給上面的變量 `view1`。
view1 = UIView()
這里是不會報錯的忿磅,因為view1
中保存的內(nèi)存地址是可以修改的糯彬。
但是如果我接著執(zhí)行下面的代碼,編譯器會不會報錯呢葱她?
view0.backgroundColor = UIColor.white
view0.backgroundColor = UIColor.black
代碼解釋:先將 view0
的背景色設置為白色
情连,然后將view0
的背景色修改為黑色
(Swift2.0和Swift3.0的修改背景色的方法有所不同,這里使用的是Swift3.0览效,只是精簡了代碼却舀,并無本質(zhì)區(qū)別)。
答案是不會的锤灿,因為在上面的操作中我并沒有修改view0
中保存的內(nèi)存地址挽拔,只是通過view0
中保存的內(nèi)存地址拿到view0
指向的對象,然后修改對象內(nèi)部的屬性(這里是backgroundColor
,還可以是frame
等等)但校,和 view0
是常量還是變量并沒有關系螃诅。
-
本質(zhì)區(qū)別
常量的值不可修改的的本質(zhì)是其保存的內(nèi)存地址不可修改,但是可以通過該地址拿到地址指向的對象并修改對象的屬性状囱。
變量的值可以修改的本質(zhì)是其保存的內(nèi)存地址能夠被修改术裸。
看到這里如果你認為關于常量和變量的知識點就這么多,那就大錯特錯了亭枷,Swift引入兩者很可能與編程范式有關袭艺。具體來說:
- let和var與函數(shù)式編程和命令式編程
let、var 這兩個關鍵字背后蘊藏著兩種截然不同的編程范式:函數(shù)式編程和命令式編程叨粘。Swift對這兩者進行了高度融合:它允許你使用引入賦值所帶來的簡單直觀的建模方法猾编。同時也鼓勵你使用不變性(常量)緩解各類并發(fā)問題。
關于常量和變量與函數(shù)式和命令式編程之間更加深入的探討請參考下面的文章升敲,其縝密的分析答倡、獨特的見解以及探索的深度和廣度是本文所不能比擬的。
Swift中的 let 和 var
值語義(不是值類型)
最后
如果文中有任何紕漏或錯誤歡迎在評論區(qū)留言指出驴党,本人將在第一時間修改過來瘪撇;喜歡我的文章,可以關注我以此促進交流學習港庄; 如果覺得此文戳中了你的G點請隨手點贊倔既;轉(zhuǎn)載請注明出處,謝謝支持攘轩。
下一篇:Swift中閉包的簡單使用