當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.7var sentence : String = "我愛吃火鍋"let open : Bool = true
//現在的寫法let price = 100 //Int
let number = 10.7 //Doublevar 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預設支持
平台名稱可以是iOS
、OSX
或watchOS
。版本號可以是大版本號像是iOS 9
,或是較小的版本像是iOS 8.3
或OSX 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算陣列長度,搭配剛剛講的(…)範圍運算子。
- 陣列
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有兩個狀態
- None:無值存在
- 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 ?? b
跟 a != nil ? a! : b
很像,可以快速把檢查與賦值一個語法完成,簡單來說 這也是一個語法糖衣。
tips
- Xcode警告為黃色標示,錯誤為紅色。警告就是代表有潛在問題,但還是可以運作。
- 註解
//單行註解
/*
多
行
/*
巢狀註解
*/
註
解
*/