# ***Swift基本語法*** - ==參考用書:iOS14 程式設計實戰 by朱克剛== ## 變數與常數宣告 > Swift語言有大小寫之分 ```swift var number = 10 var num1 = 10, num2 = 20 let pi = 3.14 ``` - var 宣告的變數可以再修改內容 - let 宣告的變數不能修改 <br> ```swift var number: Int = 10 let pi: Double = 3.14 let name: String = "Wilson" ``` - 初始化時可以明確地指出資料型態 <br> ### 命名規則 - var, let盡量不要使用 - 名稱不可以是阿拉伯數字開頭 - 1person, 10dollors - 名稱不可以有空白 - school bus - 不可以使用特殊符號(+ - * / ...),但底線是可以的 - 第一個字建議小寫 - 可以使用非英文命名 <br> ## 輸出與輸入 ### 輸出 ```swift var str = "hello" print(str) //hello ``` - 使用print()來顯示 - print()輸出結尾會換行 <br> ```swift var str = "John" print("Hi, \(str)") ``` - 可以在字串中插入變數或常數 - 語法為 \\() <br> ```swift let str = "hello" print(str + ",world") //hello,world print(str,",world") //hello ,world ``` - 可以使用+或,來合併兩字串 - +不會在兩字串內加入空白 - 使用 \\() 來合併字串比較好,才不會遇到型態不一致的問題 <br> ```swift print("Today ", terminator: "") print("is a good day") //Today is a good day print("hello", terminator: ",") print("world") //hello,world ``` - print()輸出會換行 - 不希望換行的話在print()函數中補上terminator = "",有點像python的end = "" - terminator = "xxx" 可以讓結尾是自己想要的格式 <br> ### 輸入 >須建立macOS的Command Line tool ```swift var name: String? name = readLine() ``` - readLine()是標準輸入函數 - readLine()對於App開發者並不重要,App的資料輸入是透過專門的元件<br>readLine()只有終端機程式開發者才會經常使用 ### 註解 ```swift //註解 /* 多行 註解 */ ``` - //為單行註解 - /* */為多行註解 <br> ## 基本資料型態 >Swift中所有的資料型態都是大寫開頭 ### 整數 Int - 有號整數 - Int, Int8, Int16, Int32, Int64 - 無號整數 - UInt, UInt8, Unt16, UInt32, UInt64 - 數字代表用了多少bit來儲存,Int8表示用了8個bit - 32位元作業系統 = Int32,64位元作業系統 = Int64 <br> ```swift print(Int64.max) //9223372036854775807 print(Int64.min) //-9223372036854775808 ``` - 使用max與min來取得每個數字型態範圍 <br> ```swift let bin: Int = 0b00000111//2進位 let oct: Int = 0o10//8進位 let hex: Int = 0xA//16進位 ``` - 2進位 開頭加0b - 8進位 開頭加0o - 16進位 開頭加0x <br> ```swift let n = Int.random(in: 3...50) ``` - 上面程式碼會得到範圍為3~50的整數亂數 <br> ### 浮點數 Float, Double - 有Float,Float32,Float64,Float80 與 Double - Float = Float32,使用32bit來儲存。Float64 = Double,使用64bit來儲存 - 浮點數沒有min與max屬性 <br> ```swift var n = 6.9 print(n.rounded()) //7 ``` - rounded() 用來將小數第一位做4捨5入 - rounded() 沒有提供留下幾位小數。如要留下小數3位,需要先乘上1000,四捨五入後在除1000 <br> ```swift var n = 6.0009 print(n.rounded(.up)) //7.0 print(n.rounded(.down)) //6.0 ``` - .up 為無條件進位 - .down 為無條件捨去 <br> ### 布林 Bool - 只有true, false可以放進此型態的變數或常數中 <br> ```swift var flag = true flag = !flag // flag == false ``` - ! 代表not的意思,所以!true 就是flase <br> ### 字串 String - 字串需要用雙引號包圍 <br> ```swift print("嗨\n你好") //嗨 //你好 ``` - \n = 換行,\t = TAB,\\\ = 輸出一個 \ <br> ```swift let str = """ 第一行 第二行 第三行 """ ``` - 連續三個雙引號表示多行字串 <br> ```swift let a = "abc" let b = "def" let c = a + b print(c) //c == "abcdef" ``` - 用 + 合併兩字串 <br> ### 二位元 Data - Data 可以儲存包含文字型態與非文字型態的資料 - 文字形資料指的是String形態中的資料,這些資料沒有文字編碼 - ex. mp3, mov - 用文字編輯器開啟這些檔案所看到的資料會看一堆亂碼,屬於二位元資料binary data - Data型態應用 - 藍芽資料傳輸 - 網路資料傳輸 - 各種影像,聲音資料 <br> ### 查看資料屬於何種資料型態 ```swift let n = 20 print(type(of: n)) // "Int" let str = "hello" print(type(of: str)) // "String" ``` - 使用type(of:)函數來查看所屬資料型態 <br> ### 型態轉換 - Swift在編譯前會檢查型態,通過才會開始編譯 - a and b 都是整數型態,但Int跟Int64式兩種不同的形態 - 不同的型態的資料不能放在一起運算 <br> ```swift let n = 10 let str = String(n) ``` - 整數轉字串 <br> ```swift let str = "30" let n = Int(str) ``` - 字串轉整數 <br> ```swift let n = 30 let f = Double(n) ``` - 整數轉浮點數 <br> ```swift let f = 6.9 let n = Int(f) // n == 6 ``` - 浮點數轉整數 - 相當於去掉小數 <br> ```swift let b = Bool(trincating: 1) // b == true let b = Bool(trincating: 0.3) // b == true let b = Bool(trincating: 0) // b == false let b = Bool(trincating: "true") // b == true ``` - 非0數字可以轉換為true - 數字0轉換為false <br> ### Tuple - 用小括號將兩個以上的資料組合放在一起的一種組合型資料型態 <br> ```swift var size: (Int, Int) = (1,2) var size = (1,2) ``` - 上面程式碼的 (Int, Int) 代表tuple,包含兩個Int的資料型態 - (Int, Int) 可省略,如第二行程式碼 <br> ```swift size = (600, 900) size.0 = 6 size.1 = 9 ``` - 第一個值位於tuple索引值0的位置,第二個位於1的位置 - 要修改tuple中的內容可以透過索引值或是用一個新的tuple蓋過去 <br> ```swift var size: (width: Int, height Int) size.width = 64 size.height = 81 ``` - 可以為tuple中的各部分設定標籤名稱 - 存取個別元素可以透過標籤名稱存取 <br> ```swift var size: (width: Int, height Int) size = (64, 81) var (w, h) = size // w == 64, h == 81 var (w,_) = size // w == 64 ``` - 也可以宣告數量一致的變數或常數來快速取出tuple中的值 - 不需要的可以用_代替,所以只有將1放入w中 - " _ " 是一個萬用字元,有dont care的意思 <br> ### Optional 型態 - Optimal是Swift中特殊的資料型態,代表現有每種型態能否儲存nil這個值 - nil代表空的意思,相當於C語言中的NULL - 如果一個變數或常數可能收到nil,該變數或常數的資料型態必須宣告為Optimal型態 - Optimal不是獨立的資料型態,必須和現有資料型態一起使用,因為任何資料型態都可能遇到nil <br> ```swift var x: Int? x = nil var size: (Int?, Int?)? size = nil size = (nil, 10) size = (10, nil) size = (nil, nil) ``` - Optimal型態就是在現有形態後方加上 ? - 任何資料型態都可以加上 ? 形成Optimal型態,包含tuple <br> ```swift var y: Int? = 10 let z = y print(z) // print "Optimal(10)" ``` - z = y,z取得的是不是10,而是整個y的形式 - 印出z時會得到Optimal(10)而不是單純的10,印出y也是一樣 <br> ```swift var y: Int? = 10 let z = y! print(z) // 10 ``` - 要取得原本資料型態的值(內容),需要在變數或常數後方加上!,這樣編譯器就知道我們是單純取值 <br> ```swift if y == nil{ //y的內容為nil }else{ //y的內容不為nil } ``` - 加上 ! 之前一定要確認原本值(內容)是不是nil,如果原本存的是nil,再加上!會導致錯誤 - 可以用條件判斷式來檢測 <br> ```swift var str: String = "abc" let n = Int(str) ?? 0 // n== 0 ``` - Optimal型態可以使用??來設定當值為nil的預設值 - 上面程式碼因為"abc"無法轉成數字,因此Int(str)會回傳nil,而如果回傳nil就會以0取代存入n - 這時n的資料型態是Int,不是Int? <br> ```swift var x: Int? x = x! + 1 ``` - 第一行變數x因為沒有給nil以外的值,所以x的內容為nil - 假設要將x+1,需要在非nil的情況下才可以進行,所以要先將x給一個非nil值 - 在x後面加上!取非nil的部分 - ? 改為 ! 時,稱為隱性解開 <br> ```swift var x: Int! x = 10 x = x+1 ``` - 在一開始就將驚嘆號放在資料型態後方,這樣Swift會自動幫我們取出x中非nil的值 - 一開始就隱性解開的意思 - 隱性解開優點: - 讓我們同時保有變數可以儲存nil的能力 - 隱性解開缺點: - 不容易看出變數是Optimal - 可能會導致忘記檢查nil - 建議不要使用隱性解開除非很有把握 <br> ## 流程控制 ### For-In迴圈 ```swift for 常數 in Sequence{ //code } ``` - Sequence 是一種協定,符合這個協定的有: - 陣列 - 字典 - 字串 - 範圍運算子 <br> ```swift let zoo = ["lion","tiger","elephant","snake"] for animal in zoo{ print("(animal)\ in the zoo") } //lion in the zoo //tiger in the zoo //elephant in the zoo //snake in the zoo ``` - zoo中有四個元素,所以這個迴圈會執行4次 <br> ```swift for c in "hello"{ print(c) } //h //e //l //l //o ``` - 也可以根據字串內容來決定重複次數,並取得字串中的每一個字元 <br> ```swift for i in 0...3{ print(i) } //0 //1 //2 //3 for i in 0..<3{ print(i) } //0 //1 //2 ``` - 可以根據數字範圍使用範圍運算子 - n...m代表由n到m包含m - n.\.<m代表由n到m-1 <br> ### stride函數 ```swift for i in stride(from: 4, to: 1, by: -1){ print(i) } //4 //3 //2 ``` - stride(from:to:by) - from 從多少開始 - to 到多少 - 每次進行的參數,除了是整數,也可以是浮點數 <br> ```swift let array = Array(stride(from: 4, to: 1, by: -1)) print(array) // [4,3,2] ``` - 可以像上面程式碼一樣,傳入一個陣列 <br> ```swift for _ in 1...3{ //要重複3次的程式碼 } ``` - for後方的常數如果使用底線 _ ,代表我們只在乎這個迴圈執行了幾次 <br> ### While迴圈 ```swift while 判斷式{ //要重複的程式碼 } ``` - 透過一開始的判斷式來決定是否要重複執行while區段中的程式碼 - 適合使用於程式碼不知道需要重複的場合 <br> ```swift var n = 0 while n < 5{ print(n) n += 1 } //0 //1 //2 //3 //4 ``` - 範例 <br> ```swift while true{ //需要重複的程式碼 } ``` - 用true做出無窮迴圈,在特定情況下才需使用 <br> ### repeat迴圈 ```swift repeat{ //要重複的程式碼 }while 判斷式 ``` - 跟while迴圈非常類似 - 差別在於repeat會讓迴圈內的程式碼至少執行一次 <br> ### If...else... ```swift if 判斷式{ //code }else if 判斷式{ //code }else{ //code } ``` - 只有在判斷式成立時才執行裡面的程式碼 <br> ### 比較運算子 - == - a==10 - a的內容等於10回傳true - \> - a > 10 - a的內容大於10回傳true - \< - a < 10 - a的內容小於10回傳true - \>= - a >= 10 - a的內容大於等於10回傳true - \<= - a <= 10 - a的內容小於等於10回傳true - \!= - a != 10 - a的內容不等於10回傳true <br> ### 邏輯運算子 且 && | A | B | A&&B | | :----:| :----: | :----: | | true | true | true | | true | false | false | | false | true | false | | false | false | false | - &&可以用逗點 , 取代 或 || | A | B | A\|\|B | | :----:| :----: | :----: | | true | true | true | | true | false | true | | false | true | true | | false | false | false| 否 ! | A | !A | | :----:| :----: | | true | false | | false| true | <br> ### Switch...Case - switch語句適合用來判斷數值中的各種不同狀態 ```swift var score = 80 switch score >= 60{ case true: print("pass") case false: print("failed") } ``` - 依據switch後面變數,常數的運算結果,撰寫不同的case來處理各種不同情況下要做的事 - tuple格式也可以 <br> ```swift var aqi: Int = 80 switch aqi{ case 0...50: print("very nice") case 51...100: print("nice") case 101...150: print("normal") case 151...200: print("bad") default: print("unknown") } ``` - 使用default區段來處理case沒有處理完的東西 - 可以使用範圍運算子 ... 來標定範圍 <br> ```swift var name = Earth switch name{ case "Sun": print("star") case "Earth", "Uranus", "Venus": print("planet") case "other": break } ``` - 可以將多個case合併 - case區段中如果沒有程式碼,必須加上break <br> ### Break and continue - 在迴圈中都可以使用break, continue來改變迴圈行為 - For-in, while, repeat都可使用 - break - 在迴圈中遇到break會立刻離開迴圈 - continue - continue 會立刻停止這一次的執行並回到迴圈的判斷處