回歸 Swift — DAY 1

工程師卡卡
11 min readMay 21, 2021

--

當objective-c 改為 swift 新的開始

可以使用,線上swift playground

  • 常數/變數
  • 型態
  • 簡單文字處理
  • if-else / switch / guard / assertion
  • Array
  • 了解Optional
  • tips小指南

var 宣告一個變數 let 宣告一個常數

let price = 100 //常數
var item = 10 //變數
var total = item * priceprint(total) //1000 print為印出

型態

與其他語法相同,每個常數/變數都有一種型態, swift有個強大的功能,當我們宣告一個變數/常數時可以省略型態串寫,swift編譯器可以檢查我們預設值的型態。

//完整串寫
let price : Int = 100
let number : Double = 10.7
var sentence : String = "我愛吃火鍋"let open : Bool = true
//現在的寫法let price = 100 //Int
let number = 10.7 //Double
var sentence = "我愛吃火鍋" //Stringlet open = true //Bool

簡單文字處理

var name = "Mark"
var greeting = "Hello! "
var message = greeting + name //Hello! Markmessage.uppercased() //HELLO! MARK
message.lowercased() //hello! mark
message.count //11

//swift 兩個變數/常數相加必須是同型態
let price = 100 //Intlet totalMsg = "香蕉一串“ + price //Error String 不能與 Int 相加
let totalMsg = "香蕉一串$“ + String(price) //香蕉一串$100
//字串插值
let totalMsg = "香蕉一串$\(price)" //香蕉一串$100

if-else / switch / guard / assertion

if-else

swift有提供一個非常方便的範圍運算子(…),例如:1000到2000 => 1000…2000,大於1000 => 1000…

//if-elselet a = 1                 //1if a == 1 {
print("ya!!")
} else {
print("sorry!!")
} //ya!!
//switchlet a = 1 //1switch a {
case 2:
print("ya!")
default:
print("sorry!")
} //sorry!

Fallthrough

Swift 的switch中,只要比對到一個case即會執行其內的程式,並結束這整個switch的動作,如果在特殊情況下需要執行緊接著的下一個case內的程式,就要用到fallthrough

let number7 = 5
var str4 = ""
switch number7 {
case 2,3,5,7,11,13,17,19:
str4 += "It is a prime number. "
fallthrough
case 100,200:
str4 += "Fallthrough once. "
fallthrough
default:
str4 += "Fallthrough twice."
}
// 印出:
// It is a prime number. Fallthrough once. Fallthrough twice.
print(str4)
// 雖然只比對到第一個 case 但兩個 case 都有使用 fallthrough
// 所以最後 str4 是將所有字串相加

Hint

  • 加上fallthrough後進入到的下一個case,不會對其條件做比對,而是直接執行其內的程式。

Continue

停止本次循環,進行下個循環,用在for in。

for n in 1...10 {
// n 除以 2 的餘數為零時(即 n 為偶數時)
if n % 2 == 0 {
// 停止本次循環 重新開始此流程的下個循環
continue
}
print(n)
}
// 因為當 n 為偶數時 都會走到 continue 即立即停止本次循環
// 所以會被依序印出的只有 1, 3, 5, 7, 9

Break

停止這個循環流程,switch提早結束使用。

for n in 1...10 {
// n 大於 2 時
if n > 2 {
// 立即停止這個循環流程
break
}
print(n)
}
// 當迴圈進行到第三圈時 因為 n 為 3 已經大於 2 了
// 即會進到 break 同時立即停止這個循環流程
// 所以這邊只會印出 1, 2

提前退出guard

類似if,只有false會執行,可以專注於一種條件的強況,提高可靠度。

func post (title:[String: String]) {  guard let insideTitle = title['hahahha'] else {
print('沒有這個')
return
}
print('標題是 \(indiseTitle)!')
}post(["title":"1234"])
//沒有這個
post(["title":"hahahha"])
//標題是 hahahha

斷言assertion

判斷條件是否為true,若false會被終止,true會被執行。

var age = 20
assert(age>18 , '你已經成年了')
//你已經成年了

檢測API可用性

swift 可以檢查API預設支持

平台名稱可以是iOSOSXwatchOS。版本號可以是大版本號像是iOS 9,或是較小的版本像是iOS 8.3OSX 10.10.3,以下是一個例子:

if #available(iOS 9, OSX 10.10.3, *) {
// 在 iOS 使用 iOS 9 的 API
// 在 OSX 使用 OSX 10.10.3 的 API
} else {
// 使用先前版本的 iOS 和 OSX 的 API
}

Array

陣列其實與其他語法大同小異,使用append增加陣列內容,count算陣列長度,搭配剛剛講的(…)範圍運算子。

  1. 陣列
var fruitBox = []fruitBox.append("apple")
fruitBox.append("banana")
fruitBox.append("blueberry")
print(fruitBox[1]) //bananafor i in 0...2 {
print(fruitBox[i])
}
//orfor i in 0...fruitBox.count - 1 {
print(fruitBox[i])
}
//orfor fruit in fruitBox {
print(fruit)
}
//以上結果會一樣,將陣列都印出來

2. 集合型態陣列 — 字典dictionary(也就是有key與value的陣列)

何時會用到字典?

就是有需要作查詢的時候方便(!?)

//key編號/value水果var fruitBox = ["1001": "apple","1002": "banana","1003": "blueberry"]print(fruitBox["1002"]) //bananafor (key, value) in fruitBox {
print("編號:\(key)")
print("水果:\(value)")
}
// tip: 字串插值"\(key)"
// 會印出以下答案
編號:1001
水果:apple
編號:1002
水果:banana
編號:1003
水果:blueberry

了解Optionals

以安全做為訴求的 Swift 設計成所有的變數在賦值時只能有值,不能是 nil ,只要接受到 nil ,就會拋出錯誤。

但變數還是有可能有nil的可能性呀!

因此Optional 是在 Swift 中,做為主動描述變數是否存在 nil 值情況判斷的機制,目的是為了減少變數在傳遞過程,可能存在 nil 的不確定性,可以立即明確地處理 nil 發生時的情況,並且可以在 編譯時期 (compile time) 就檢查對於 nil 的處理是否合法,以減少應用程式 crash 的機會。

宣告Optional

  • Optional 是個包裝(wrapp)型別的容器,可以不給初始值,也可以給初始值。在型別後面加上?表示變數是個 Optional。切記問號需緊貼著型別,型別與?之間不可留空白。而問號原本的意思,就是代表有或沒有,因此完全說明了,它可能有值,也可能無值。
  • Optional 預設值為nil,因此宣告後沒有給初始值,則自動設定為nil。

Optional有兩個狀態

  1. None:無值存在
  2. Some:有值存在

封裝在optional

var boyfriend : String?  //nil  沒男友的時候,使用optional給與空值
var boyfriend : String? = nil //與上面結果相同

解封裝optional

optional 變數/常數儲存的內容是被包裝起來的,我們需要解開包裝,才能讀取它的內容。optional 變數/常數內容被裝在一個盒子裡。當它沒有內容時,盒子是空的。當我們存了字串到裡面時,盒子裡其實有東西,但是沒打開看不到,也因此我們要使用”!”驚嘆號來解封裝。

var boyfriend : String? = "Ryan" 
boyfriend = "可愛的 \(boyfriend)"
//"可愛的 Optional(\"Ryan\") 因為我們沒有將optional解封裝
boyfriend = "可愛的 \(boyfriend!)"
//可愛的 Ryan 在變數/常數後面加上!即可

了解optional後,倘若後面宣告變數/常數時,可以先思考是否有空值的可能性!看需不需要使用到optional

if-else optional延伸,有值的話接著取值的 Optional Binding

由於大部份的時候我們只是想讀取內容,而不是修改,所以採用 if let 居多,在使用判斷式時不需要使用!就可以賦予值給變數/常數。

var boyfriend : String? = "Ryan"if let boyfriend = boyfriend {
boyfriend = "可愛的 \(boyfriend)"
}else{
var meg = "單身喔喔"
}
// Ryanvar boyfriend : String? = nilif let boyfriend = boyfriend {
boyfriend = "可愛的 \(boyfriend)"
}else{
var meg = "單身喔喔"
}
// 單身喔喔

自動取值的Implicitly Unwrapped Optional

若是變數/常數可能無值,但它大多數時候有值,或是一旦被設定內容後,就會保持在有值的狀態,不會再變成 nil,即可使用。

var boyfriend : String! = "Ryan" 
boyfriend = "可愛的 \(boyfriend)" // Error

也就是在宣告的時候就直接使用!,自動取值為我們帶來很大的方便,但它也有潛藏的危險。若是 optional 變數(常數)為 nil,一樣的,取值將帶來可怕的閃退。

所以需加上判斷式:

var boyfriend : String! = "Ryan" if boyfriend != nil {
boyfriend = "可愛的 \(boyfriend)"
} else {
let meg = "Sorry!"
}

// 可愛的Ryan

Swift給了一個方便的寫法(語法糖)

物件?.屬性1?.屬性2

也就是 Swift會逐層檢查,遇到 nil時就會停下來了,以上述例子來說,多層的 Optional Binding可以簡化為一層,而不需要再以多層 Optional Binding的方式檢查屬性了

另外由於 Optional需要包裹 nil以保持安全的原因,所以 Optional經過Optional Chaining還是會是 Optional,要使用還是需經過一次 unwrap

if let name = people3?.name {
print("My name is \(name)!")
}

而在 Swift 1.0 ,導入了 ?? (Nil Coalescing Operator) 這個語法來簡化 Unwrapping 的過程。 他的規則是,如果 ?? 左邊有值,就取左邊原本的值,如果左邊是一個 nil ,那就改取右邊的值。

???: 很像,可以快速把檢查與賦值一個語法完成,簡單來說 這也是一個語法糖衣。

a ?? b // a if a is not nil else b

a ?? ba != nil ? a! : b 很像,可以快速把檢查與賦值一個語法完成,簡單來說 這也是一個語法糖衣。

tips

  • Xcode警告為黃色標示,錯誤為紅色。警告就是代表有潛在問題,但還是可以運作。
  • 註解
    //單行註解
    /*


    /*
    巢狀註解
    */


    */

--

--

工程師卡卡
工程師卡卡

Written by 工程師卡卡

Frontend developer Swift baby level

No responses yet