iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
1

前言

是的!語法居然寫了三天!!沒辦法,我自己可是讀了一個多月還沒完全搞懂swift語法,對於一個新手而言,語法真的是基礎中的基礎,真的要不時拿回來翻閱一下,相信你會有新的理解與發現。

前兩天跟各位介紹了一些語法,雖然不是全部的內容,但也是我精心挑選的重點,大家可以參考看看,但是千萬不要因為這樣就不閱讀官方手冊!!我說過官方手冊寫得非常詳盡,真的要好好拜讀一下!!

Nil與問號

相信大家都讀過『哈利波特』這本小說吧?傳說中的「那個人」,那個看似不存在,卻真真實實存在的大壞蛋也是有名字的—『佛地魔』。

沒錯,swift裡也有一個看似不存在,卻有個名字的『nil』(我稱為『空值』),大家應該有看過Excel裡出現的NULL(無值)或者N/A(不適用),這裡的nil就是這個概念。

因為程式執行時,最怕意外出現nil導致程式崩潰,因此swift透過許多機制(例如問號、驚嘆號、if let...等)來強制使用者處理nil,以提升App的穩定度。

假設我們設計一個表單請使用者填入名字,因為我們一開始不知道使用者名字,因此我們預設一個顯示值

var name: String
name = "default name" //印出"deafault name"

但是萬一使用者還是 很白目 沒有輸入名字就回傳表單,那就會出現nil的狀況了,因此我們必須要在資料型態後面加上「?」,避免程式崩潰

var name: String?
name = nil //編譯不會出現錯誤,name也確實填入nil

但是大部分使用者通常都會照實輸入名字。當一個非nil的值存入name的變數,之後我們再取出這個變數後面就要加上驚嘆號,代表要取出非nil的值。

var name: String?
name = "Charlie"
print ("\(name!)")

如果name後面不加入驚嘆號,Xcode會出現警示,提醒設計師這裡可能會出現不確定的bug!驚嘆號在這裡的意思是「我確定取出得值不會是nil」,所以如果name的內容是nil,App就會在這一行崩潰。

可是就是有使用者會 白目不填 忘記填入名字啊??那name還是會出現nil導致App崩潰啊...
沒錯!!所以出現了兩個問號

兩個問號 - ??

如果某個變數可能是nil時,可以使用??來給予一個預設值。延續上個例子

var name: String?
name = nil
print ("\(name ?? "I don't know your name.")")
//印出"I don't know your name."
name = "Charlie"
print ("\(name ?? "I don't know your name.")")
//印出"Charlie"
name ?? "I don't know your name."

這段程式碼意思就是,當name 是 nil時就回傳"I don't know your name.”,如果name有值,就回傳該值。

if let / if var語法

如果一個運算式,其中變數必須要有值,而使用者可能輸入一個nil的值,那我們就必須先判斷變數是否為nil。

假設我們請使用者輸入一個數字的字串text,而這個字串我們拿來轉換成數字進行運算。

var text = "12"
var num = Int(text)

let calculate = num! / 3

這時候就要小心使用者輸入了非數字的字串,導致num在轉換成數字時變成nil,為了避免這格狀況我們一定要先檢查num是否為nil

var text = "12"
var num = Int(text)

if num != nil {
    let calculate = num! / 3
    print(calculate)
}

此外,Swift提供了新的語法,可以將判別式改寫為:

var text = "12"

if let num = Int(text) {
    let calculate = num / 3
    print(calculate)
}

If let num = Int(text)這段程式碼共做了三件事

  1. Int(text):將字串text轉換成整數型態
  2. if:確認Int(text)是否為nil
  3. let num =:當Int(text)不為nil時,將值儲存進常數num中

PS1:請注意,這裡的等號只有一個,是確認等號右邊不為nil時,將值存入等號左邊,也因為確定該常數非nil了,函數中取用該常數時可以不用再加驚嘆號。(雙等號才是確認左右兩側的值是否相等。)

PS2:當然也可以寫成if var,這樣函數中取用這個變數時可以任意修改

最後最後再提一個小例子,因為swift允許等號左右兩側使用相同命名,因此有時候會看到自己等於自己的狀況發生

var name: String?
name = "Charlie"
if let name = name {
    print("Hello, \(name)!")
}
//印出"Hello, Charlie!"

存取控制

Swift針對類別、結構、變數或是函數的存取權限定義了五種不同等級:

  • open代表不同模組也可以繼承也能存取。

  • public代表模組內可以繼承、覆寫,模組外雖然看得到,但只能使用,不能繼承也不能覆寫。

  • internal為預設等級,在同一個模組內可以繼承、覆寫,但在模組外則完全看不到。

  • fileprivate代表同一個檔案內可以存取。

  • private代表只要不在該類別中的程式碼就無法存取。Swift 4開始,允許extension中的程式可以存取原本類別中的private等級變數或函數,但extension必須與原類別在同一個檔案中。

用法只要在該宣告最前方加上該字樣即可

class someClass {
    open var name: String?
    private var age: Int?
    public var emailAddress: String?
}

萬歲~~我總算寫完語法的部分了,我得再強調一次,這些只是我看完官方手冊以整理出來的筆記,並不是全部語法內容!!請大家真的要認真去看官方手冊啊~~~


上一篇
Day 3 - swift 語法 (part II)
下一篇
Day 5 - Xcode
系列文
無中生有-從SWIFT語法學習到iOS APP的開發30

2 則留言

0
shavenking
iT邦新手 5 級 ‧ 2017-12-23 11:31:08

Hi 樓主安安,請問模組的定義是什麼?一個 Class 是一個模組嗎?

soj iT邦新手 5 級‧ 2017-12-26 10:05:52 檢舉

這裡模組主要指的是定義在framework中的類別

請問framework該如何解釋呢?跟architecture有什麼差別?

0
陳董 Don
iT邦新手 5 級 ‧ 2017-12-23 16:41:38

素晴らしい

我要留言

立即登入留言