關(guān)于iOS Coding過程中經(jīng)常遇到各種小問題或是一些疑惑,整理收集如下.
缺省參數(shù)
今天在寫一個(gè)UILabel生成方法時(shí)官套,突然想到去年剛開始接觸Object-C時(shí)就曾一直疑惑,語言層級(jí)特性(語法糖)是否支持類似C#中缺省參數(shù)的功能?
缺省參數(shù)(Default Argument Value)惋嚎,顧名思義站刑,就是在聲明函數(shù)的某個(gè)參數(shù)的時(shí)候?yàn)橹付ㄒ粋€(gè)默認(rèn)值. 在調(diào)用該方法時(shí)要是傳入了這個(gè)參數(shù),則使用傳入的值绞旅,如果缺少這個(gè)輸入?yún)?shù),那么直接使用設(shè)定的默認(rèn)值進(jìn)行調(diào)用. 例如在C#語法中聲明一個(gè)缺省參數(shù)的方法:
調(diào)用方法時(shí)自由地選擇采用缺省的參數(shù)值,或者覆蓋參數(shù)缺省值:
在方法聲明和調(diào)用時(shí)極大簡化語法中贝,代碼寫起來短小精悍,具有較高的自由性同時(shí)代碼也易讀理解.但其實(shí)Object-C語法層面本身并不支持缺省參數(shù)蝎土,自然沒法能夠直接實(shí)現(xiàn)類似C#語言中的寫法.但真的無法實(shí)現(xiàn)嗎?雖然語法層面不能直接支持绣否,其實(shí)是可以的只是有點(diǎn)繞.
笨一點(diǎn)的方式定義方法時(shí)聲明該參數(shù),在方法實(shí)現(xiàn)時(shí)內(nèi)部處理默認(rèn)值.類似:
如上我們定義一個(gè)UILabel蒜撮,默認(rèn)文字顏色是紅色,但不是每次都會(huì)定義, 那在定義方法時(shí)做一個(gè)內(nèi)部約定,當(dāng)defineColor傳入為nil取逾,就是取其默認(rèn)值為紅色苹支,如果為非nil時(shí)則正常賦值. 這種寫法偏向于在方法內(nèi)定義了一個(gè)約定,邏輯簡單债蜜,但在方法聲明層面上如果不知道隱藏潛在約定代碼邏輯或者沒有很好注釋說明,對(duì)調(diào)用者來說跟defineColor和orginStr兩個(gè)參數(shù)并沒有什么區(qū)別的.難道沒有更好的方式嗎? 有.
改良一下替代的方法儒洛,其實(shí)是定義兩個(gè)方法, 一個(gè)方法聲明時(shí)包含所有缺省參數(shù)狼速,用另外一個(gè)則不包含缺省參數(shù)方法調(diào)用前者即可. 這種方式優(yōu)點(diǎn)將使用默認(rèn)值的參數(shù)放在函數(shù)的參數(shù)列表的末尾寫法, 確保了所有調(diào)用函數(shù)的非默認(rèn)參數(shù)使用相同的順序, 并明確地表示在每種情況下相同的函數(shù)調(diào)用. ?在聲明層面能夠很好區(qū)分方法實(shí)現(xiàn), 而不存在額外的歧義. 這種折中的方式缺點(diǎn)是同一個(gè)功能實(shí)現(xiàn)多了一個(gè)不同的入口, 一定程度增加代碼的復(fù)雜度. Objective-C 由于語法的特點(diǎn)幾乎無法在不大幅改動(dòng)的情況下很好地實(shí)現(xiàn)缺省參數(shù).Objective-C 社區(qū)詬病很多年的這一特性, 而作為其的繼任者Swift語言是否能夠在語法上友好的支持? 答案是自然肯定的.
如上可見Swift能夠完美的實(shí)現(xiàn)方法的缺省參數(shù).但如果在深入一點(diǎn),你會(huì)有驚喜發(fā)現(xiàn).在C#中我們知道方法實(shí)現(xiàn)缺省參數(shù)并沒有問題浅浮,而不要忘了語法上還有一個(gè)限制條件:
調(diào)用時(shí)你只能從最后一個(gè)參數(shù)開始進(jìn)行省略, 如果你要省略一個(gè)參數(shù),你必須省略它后面所有的參數(shù)滚秩,即:帶缺省值的參數(shù)必須放在參數(shù)表的最后面.
類似如果我在C#這樣寫法:
缺省參數(shù)聲明是寫在最前面, 編譯器會(huì)直接報(bào)錯(cuò),而相反Swift更為自由本股,則沒有類似C#這樣語法限制桐腌,如果同樣語法在Swift則是可以編譯通過的拄显,如下:
正是因?yàn)?b>Swift語法中沒有"默認(rèn)參數(shù)之后不能再出現(xiàn)無默認(rèn)值的參數(shù)"這樣的規(guī)則案站,上面方法的聲明在 Swift 里都是合法可用的.
當(dāng)然針對(duì)Swift中值得一提的是,默認(rèn)參數(shù)都是需要外部標(biāo)簽的承边,如果沒有指定外部標(biāo)簽,那么 Swift 會(huì)默認(rèn)自動(dòng)加上同名的標(biāo)簽石挂,也就相當(dāng)于在參數(shù)聲明前加上井號(hào)#。實(shí)際上我們聲明的sayHello和sayHello1的符號(hào)是這樣的:
外部標(biāo)簽名意義在于痹愚,不像其他普通方法調(diào)用那樣省掉第一個(gè)參數(shù)標(biāo)簽名,這是為了不產(chǎn)生參數(shù)命名上的歧義.
關(guān)于缺省參數(shù)演示的代碼在這里[DefaultArgumengSample github]