Swift中的常量和變量

前言

Swift作為一門新語言,對(duì)于熟練掌握Objective-C編程的iOS開發(fā)者來說其實(shí)很容易上手,但其在語法和編程習(xí)慣上改變了很多,對(duì)于從未了解Objective-C語言而從Swift開始學(xué)習(xí)iOS開發(fā)的新手來說可能上手有一定難度,下面我將這段時(shí)間的學(xué)習(xí)成果結(jié)合官方文檔說明做一個(gè)簡單的匯總,希望可以幫助到正在學(xué)習(xí)Swift的小伙伴們。
本文主要是介紹Swift中最常用的常量和變量,將從常量和變量的 定義與申明命名規(guī)范兩者的深入思考 三個(gè)方面入手,入門基礎(chǔ)篇,重點(diǎn)介紹變量和常量的使用以及區(qū)別,希望大家在閱讀完本文后都可以熟練使用它們。

常量和變量的定義與申明

常量和變量把名字和一個(gè)特定類型的值關(guān)聯(lián)起來。常量的值一旦設(shè)置好便不能再被更改,然而變量可以在將來被設(shè)置為不同的值。

  • 申明
    常量和變量必須在使用前被聲明,使用關(guān)鍵字 let 來聲明常量,使用關(guān)鍵字 var 來聲明變量。舉個(gè)簡單的例子:
class Person: NSObject {
    let life = 1
    var age = 0
}

這里我們有一個(gè)Person類繼承NSObject,顯然人的生命只有一條應(yīng)該設(shè)置為不可以改變的常量,但是人的年齡是隨著時(shí)間變化的應(yīng)該聲明為變量,同理,當(dāng)你在開發(fā)過程中有類似需求時(shí)應(yīng)該這樣來選擇何時(shí)使用變量、何時(shí)使用常量。
當(dāng)然我們可以選擇一行代碼以逗號(hào)分隔的形式申明多個(gè)簡單的變量或常量如下所示:

 var a = 0, b = 1.0, c = "CoderYQ" 
  • Swift中的類型安全和類型推斷
    Swift 是一門類型安全的語言,即你必須時(shí)刻清楚此時(shí)代碼需要處理的值的類型,編譯器會(huì)進(jìn)行類型檢查,任何不匹配的類型都會(huì)被標(biāo)記為錯(cuò)誤當(dāng)然更不能參與運(yùn)算。當(dāng)你操作不同類型的值時(shí),類型檢查能幫助你避免錯(cuò)誤。當(dāng)然并不是所有的變量和常量都需要明確指出一個(gè)確定的類型,如果你沒有為申明的變量或常量指定類型,Swift 會(huì)使用類型推斷的功能推斷出合適的類型,通過檢查你給變量賦的值,類型推斷能夠在編譯階段自動(dòng)的推斷出值的類型,這就是Swift中類型推斷

    就像上面的連續(xù)申明變量abc的代碼中我們并沒有明確指出三者的類型,編譯器則是通過你給三者賦的值來推斷三者的類型分別為:Int類型、Double類型、String類型。
    但是在某些必要時(shí)刻我們是需要給申明的變量或常量提供類型標(biāo)注的,以此來明確他們能夠存儲(chǔ)的值。添加類型標(biāo)注的方法是在變量或常量的名字后邊加一個(gè)冒號(hào),再跟一個(gè)空格,最后加上要使用的類型名稱(這里和Objective-C中不太一樣),如下所示的代碼效果其實(shí)和上面的是一樣的:

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"

官方文檔對(duì)于命名規(guī)范還有這樣的要求:

常量和變量的名字不能包含空白字符數(shù)學(xué)符號(hào)箭頭保留的(或者無效的)Unicode 碼位連線制表符。也不能以數(shù)字開頭,盡管數(shù)字幾乎可以使用在名字其他的任何地方。
一旦你聲明了一個(gè)確定類型的常量或者變量,就不能使用相同的名字再次進(jìn)行聲明,也不能讓它改存其他類型的值。常量和變量之間也不能互換,如果你需要使用 Swift 保留的關(guān)鍵字來給常量或變量命名,可以使用反引號(hào)( ` )包圍它來作為名稱。總之,除非別無選擇,避免使用關(guān)鍵字作為名字除非你確實(shí)別無選擇。

總結(jié)一句:Swift中變量和常量的命名相較于Objective-C中更加靈活多變,但是仍然有上面的規(guī)定需要注意,而且他們的命名盡量做到見名知意,以便于開發(fā)人員之間的協(xié)同合作。這里我給大家列出了Swift中主要的關(guān)鍵字,希望大家在命名的時(shí)候盡量規(guī)避他們。

  • 用作聲明的關(guān)鍵字:
class、deinit、enum、extension、func、import、init、let、protocol、static、struct、subscript、typealias、var
  • 用作語句的關(guān)鍵字:
break、case、continue、default、do、else、fallthrough、if、in、for、return、switch、where、while
  • 用作表達(dá)和類型的關(guān)鍵字:
as、dynamicType、is、new、super、self、Self、Type、__COLUMN__、__FILE__、__FUNCTION__、__LINE__
  • 特定上下文中被保留的關(guān)鍵字:
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)過上面的學(xué)習(xí)我們已經(jīng)能夠熟練使用常量和變量了,那么兩者之間在使用上到底有何區(qū)別呢?這里通過例子說明一下:

//通過 UIView() 方法創(chuàng)建一個(gè) UIView 的對(duì)象
//(假設(shè)系統(tǒng)分配的內(nèi)存地址為:0x7faa31616bb0)并賦值給申明為 UIView類型 的常量:view0
let view0 : UIView = UIView()

//通過 UIView() 方法創(chuàng)建另外一個(gè) UIView 的對(duì)象
//(假設(shè)系統(tǒng)分配的內(nèi)存地址為:0x7f9890c062b0) 并賦值給申明為 UIView類型 的變量:view1
var view1 : UIView = UIView()
  • 第一行代碼的意思:首先在內(nèi)存中的堆區(qū)創(chuàng)建一個(gè)內(nèi)存地址為0x7faa31616bb0UIView類型的對(duì)象,然后在內(nèi)存中的棧區(qū)申明一個(gè)名為view0的常量指向該對(duì)象,即view0中保存的是0x7faa31616bb0這個(gè)地址,而且該常量的值是不可變的(這不廢話嗎),即view0中保存的內(nèi)存地址不能變了。

  • 第二行代碼的意思: 在堆區(qū)又創(chuàng)建一個(gè)新的內(nèi)存地址為0x7f9890c062b0UIView類型的對(duì)象,然后在棧區(qū)又申明一個(gè)名為view1的變量指向該對(duì)象,即view0中保存的是0x7faa31616bb0這個(gè)地址,注意此時(shí)view1的值是可以改變的,即view1中保存的內(nèi)存地址是可以變化的。

如果此時(shí)執(zhí)行下面的操作:

//重新創(chuàng)建一個(gè)新的 `UIView` 的對(duì)象
//(假設(shè)系統(tǒng)分配的內(nèi)存地址為:`0x7f9890c042b0`)并賦值給上面的常量 `view0`
view0 = UIView()

編譯器會(huì)報(bào)這樣的錯(cuò)誤:

 error: cannot assign to value: 'view0' is a 'let' constant,
change 'let' to 'var' to make it mutable

錯(cuò)誤原因:創(chuàng)建一個(gè)新的對(duì)象有一個(gè)新的內(nèi)存地址,你把新的對(duì)象重新賦值給view0,即view0現(xiàn)在指向另一個(gè)對(duì)象了,相當(dāng)于將view0中的原來存儲(chǔ)的0x7faa31616bb0內(nèi)存地址修改成了0x7f9890c042b0,但是view0中存儲(chǔ)的內(nèi)存地址一旦賦值了是不能修改的,所以編譯器這里就報(bào)錯(cuò)了,他建議你將 let 變成 var 來申明 view0

//重新創(chuàng)建一個(gè)新的 `UIView` 的對(duì)象
//(假設(shè)系統(tǒng)分配的內(nèi)存地址為:`0x7f9890c042b0`)并賦值給上面的變量 `view1`。
view1 = UIView()

這里是不會(huì)報(bào)錯(cuò)的,因?yàn)?code>view1中保存的內(nèi)存地址是可以修改的。
但是如果我接著執(zhí)行下面的代碼,編譯器會(huì)不會(huì)報(bào)錯(cuò)呢?

view0.backgroundColor = UIColor.white
view0.backgroundColor = UIColor.black

代碼解釋:先將 view0 的背景色設(shè)置為白色,然后將view0的背景色修改為黑色(Swift2.0和Swift3.0的修改背景色的方法有所不同,這里使用的是Swift3.0,只是精簡了代碼,并無本質(zhì)區(qū)別)。
答案是不會(huì)的,因?yàn)樵谏厦娴牟僮髦形也]有修改view0中保存的內(nèi)存地址,只是通過view0中保存的內(nèi)存地址拿到view0指向的對(duì)象,然后修改對(duì)象內(nèi)部的屬性(這里是backgroundColor,還可以是frame等等),和 view0 是常量還是變量并沒有關(guān)系。

  • 本質(zhì)區(qū)別
    常量的值不可修改的的本質(zhì)是其保存的內(nèi)存地址不可修改,但是可以通過該地址拿到地址指向的對(duì)象并修改對(duì)象的屬性。
    變量的值可以修改的本質(zhì)是其保存的內(nèi)存地址能夠被修改。

看到這里如果你認(rèn)為關(guān)于常量和變量的知識(shí)點(diǎn)就這么多,那就大錯(cuò)特錯(cuò)了,Swift引入兩者很可能與編程范式有關(guān)。具體來說:

  • let和var與函數(shù)式編程和命令式編程

letvar 這兩個(gè)關(guān)鍵字背后蘊(yùn)藏著兩種截然不同的編程范式:函數(shù)式編程和命令式編程。Swift對(duì)這兩者進(jìn)行了高度融合:它允許你使用引入賦值所帶來的簡單直觀的建模方法。同時(shí)也鼓勵(lì)你使用不變性(常量)緩解各類并發(fā)問題。

關(guān)于常量和變量與函數(shù)式和命令式編程之間更加深入的探討請參考下面的文章,其縝密的分析、獨(dú)特的見解以及探索的深度和廣度是本文所不能比擬的。
Swift中的 let 和 var
值語義(不是值類型)

最后

如果文中有任何紕漏或錯(cuò)誤歡迎在評(píng)論區(qū)留言指出,本人將在第一時(shí)間修改過來;喜歡我的文章,可以關(guān)注我以此促進(jìn)交流學(xué)習(xí); 如果覺得此文戳中了你的G點(diǎn)請隨手點(diǎn)贊;轉(zhuǎn)載請注明出處,謝謝支持。

下一篇:Swift中閉包的簡單使用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,401評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,635評(píng)論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,128評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,365評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,881評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,733評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,935評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,172評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評(píng)論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,595評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,908評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容