歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Swift 基礎語法

Swift 基礎語法

日期:2017/3/1 9:17:19   编辑:Linux編程

一、變量和常量

定義

  • let 定義常量,一經賦值不允許再修改
  • var 定義變量,賦值之後仍然可以修改
//: # 常量
//: 定義常量並且直接設置數值
let x = 20
//: 常量數值一經設置,不能修改,以下代碼會報錯
// x = 30

//: 使用 `: 類型`,僅僅只定義類型,而沒有設置數值
let x1: Int
//: 常量有一次設置數值的機會,以下代碼沒有問題,因為 x1 還沒有被設置數值
x1 = 30
//: 一旦設置了數值之後,則不能再次修改,以下代碼會報錯,因為 x1 已經被設置了數值
// x1 = 50

//: # 變量
//: 變量設置數值之後,可以繼續修改數值
var y = 200
y = 300

自動推導

  • Swift能夠根據右邊的代碼,推導出變量的准確類型
  • 通常在開發時,不需要指定變量的類型
  • 如果要指定變量,可以在變量名後使用:,然後跟上變量的類型

重要技巧:Option + Click 可以查看變量的類型

沒有隱式轉換!!!

  • Swift 對數據類型要求異常嚴格
  • 任何時候,都不會做隱式轉換

如果要對不同類型的數據進行計算,必須要顯式的轉換

let x2 = 100
let y2 = 10.5

let num1 = Double(x2) + y2
let num2 = x2 + Int(y2)

let & var 的選擇

  • 應該盡量先選擇常量,只有在必須修改時,才需要修改為 var
  • 在 Xcode 7.0 中,如果沒有修改變量,Xcode 會提示修改為 let

二、Optional 可選類型

  • Optional 是 Swift 的一大特色,也是 Swift 初學者最容易困惑的問題
  • 定義變量時,如果指定是可選的,表示該變量可以有一個指定類型的值,也可以是 nil
  • 定義變量時,在類型後面添加一個 ?,表示該變量是可選的
  • 變量可選項的默認值是 nil
  • 常量可選項沒有默認值,主要用於在構造函數中給常量設置初始數值
//: num 可以是一個整數,也可以是 nil,注意如果為 nil,不能參與計算
let num: Int? = 10
  • 如果 Optional 值是 nil,不允許參與計算
  • 只有解包(unwrap)後才能參與計算
  • 在變量後添加一個 !,可以強行解包

注意:必須要確保解包後的值不是 nil,否則會報錯

//: num 可以是一個整數,也可以是 nil,注意如果為 nil,不能參與計算
let num: Int? = 10

//: 如果 num 為 nil,使用 `!` 強行解包會報錯
let r1 = num! + 100

//: 使用以下判斷,當 num 為 nil 時,if 分支中的代碼不會執行
if let n = num {
    let r = n + 10
}

常見錯誤

unexpectedly found nil while unwrapping an Optional value

翻譯

在[解包]一個可選值時發現 nil

?? 運算符

  • ?? 運算符可以用於判斷 變量/常量 的數值是否是 nil,如果是則使用後面的值替代
  • 在使用 Swift 開發時,?? 能夠簡化代碼的編寫
let num: Int? = nil

let r1 = (num ?? 0) + 10
print(r1)

三、控制流

if

  • Swift 中沒有 C 語言中的非零即真概念
  • 在邏輯判斷時必須顯示地指明具體的判斷條件 true / false
  • if 語句條件的 () 可以省略
  • 但是 {} 不能省略
let num = 200
if num < 10 {
    print("比 10 小")
} else if num > 100 {
    print("比 100 大")
} else {
    print("10 ~ 100 之間的數字")
}

三目運算

  • Swift 中的 三目 運算保持了和 OC 一致的風格
var a = 10
var b = 20
let c = a > b ? a : b
print(c)

適當地運用三目,能夠讓代碼寫得更加簡潔

可選類型判斷

  • 由於可選類型的內容可能為 nil,而一旦為 nil 則不允許參與計算
  • 因此在實際開發中,經常需要判斷可選類型的內容是否為 nil

單個可選類型判斷

let url = NSURL(string: "http://www.baidu.com")

//: 方法1: 強行解包 - 缺陷,如果 url 為空,運行時會崩潰
let request = NSURLRequest(URL: url!)

//: 方法2: 首先判斷 - 代碼中仍然需要使用 `!` 強行解包
if url != nil {
    let request = NSURLRequest(URL: url!)
}

//: 方法3: 使用 `if let`,這種方式,表明一旦進入 if 分支,u 就不在是可選類型
if let u = url where u.host == "www.baidu.com" {
    let request = NSURLRequest(URL: u)
}

可選類型條件判斷

//: 1> 初學 swift 一不小心就會讓 if 的嵌套層次很深,讓代碼變得很丑陋
if let u = url {
    if u.host == "www.baidu.com" {
        let request = NSURLRequest(URL: u)
    }
}

//: 2> 使用 where 關鍵字,
if let u = url where u.host == "www.baidu.com" {
    let request = NSURLRequest(URL: u)
}
  • 小結
    • if let 不能與使用 &&|| 等條件判斷
    • 如果要增加條件,可以使用 where 子句
    • 注意:where 子句沒有智能提示

多個可選類型判斷

//: 3> 可以使用 `,` 同時判斷多個可選類型是否為空
let oName: String? = "張三"
let oNo: Int? = 100

if let name = oName {
    if let no = oNo {
        print("姓名:" + name + " 學號: " + String(no))
    }
}

if let name = oName, let no = oNo {
    print("姓名:" + name + " 學號: " + String(no))
}

判斷之後對變量需要修改

let oName: String? = "張三"
let oNum: Int? = 18

if var name = oName, num = oNum {

    name = "李四"
    num = 1

    print(name, num)
}

guard

  • guard 是與 if let 相反的語法,Swift 2.0 推出的
let oName: String? = "張三"
let oNum: Int? = 18

guard let name = oName else {
    print("name 為空")
    return
}

guard let num = oNum else {
    print("num 為空")
    return
}

// 代碼執行至此,name & num 都是有值的
print(name)
print(num)
  • 在程序編寫時,條件檢測之後的代碼相對是比較復雜的
  • 使用 guard 的好處
    • 能夠判斷每一個值
    • 在真正的代碼邏輯部分,省略了一層嵌套

switch

  • switch 不再局限於整數
  • switch 可以針對任意數據類型進行判斷
  • 不再需要 break
  • 每一個 case後面必須有可以執行的語句
  • 要保證處理所有可能的情況,不然編譯器直接報錯,不處理的條件可以放在 default 分支中
  • 每一個 case 中定義的變量僅在當前 case 中有效,而 OC 中需要使用 {}
let score = "優"

switch score {
case "優":
    let name = "學生"
    print(name + "80~100分")
case "良": print("70~80分")
case "中": print("60~70分")
case "差": print("不及格")
default: break
}
  • switch 中同樣能夠賦值和使用 where 子句
let point = CGPoint(x: 10, y: 10)
switch point {
case let p where p.x == 0 && p.y == 0:
    print("中心點")
case let p where p.x == 0:
    print("Y軸")
case let p where p.y == 0:
    print("X軸")
case let p where abs(p.x) == abs(p.y):
    print("對角線")
default:
    print("其他")
}
  • 如果只希望進行條件判斷,賦值部分可以省略
switch score {
case _ where score > 80: print("優")
case _ where score > 60: print("及格")
default: print("其他")
}

四、for 循環

  • OC 風格的循環
var sum = 0
for var i = 0; i < 10; i++ {
    sum += i
}
print(sum)
  • for-in,0..<10 表示從0到9
sum = 0
for i in 0..<10 {
    sum += i
}
print(sum)
  • 范圍 0...10 表示從0到10
sum = 0
for i in 0...10 {
    sum += i
}
print(sum)
  • 省略下標
    • _ 能夠匹配任意類型
    • _ 表示忽略對應位置的值
for _ in 0...10 {
    print("hello")
}

五、字符串

在 Swift 中絕大多數的情況下,推薦使用 String 類型

  • String 是一個結構體,性能更高
    • String 目前具有了絕大多數 NSString 的功能
    • String 支持直接遍歷
  • NSString 是一個 OC 對象,性能略差
  • Swift 提供了 StringNSString 之間的無縫轉換

字符串演練

  • 遍歷字符串中的字符
for s in str.characters {
    print(s)
}
  • 字符串長度
// 返回以字節為單位的字符串長度,一個中文占 3 個字節
let len1 = str.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
// 返回實際字符的個數
let len2 = str.characters.count
// 返回 utf8 編碼長度
let len3 = str.utf8.count
  • 字符串拼接
    • 直接在 "" 中使用 \(變量名) 的方式可以快速拼接字符串
let str1 = "Hello"
let str2 = "World"
let i = 32
str = "\(i) 個 " + str1 + " " + str2

我和我的小伙伴再也不要考慮 stringWithFormat 了 :D

  • 可選項的拼接
    • 如果變量是可選項,拼接的結果中會有 Optional
    • 為了應對強行解包存在的風險,蘋果提供了 ?? 操作符
    • ?? 操作符用於檢測可選項是否為 nil
      • 如果不是 nil,使用當前值
      • 如果是 nil,使用後面的值替代
let str1 = "Hello"
let str2 = "World"
let i: Int? = 32
str = "\(i ?? 0) 個 " + str1 + " " + str2
  • 格式化字符串
    • 在實際開發中,如果需要指定字符串格式,可以使用 String(format:...) 的方式
let h = 8
let m = 23
let s = 9
let timeString = String(format: "%02d:%02d:%02d", arguments: [h, m, s])
let timeStr = String(format: "%02d:%02d:%02d", h, m, s)

String & Range 的結合

  • 在 Swift 中,StringRange連用時,語法結構比較復雜
  • 如果不習慣 Swift 的語法,可以將字符串轉換成 NSString 再處理
let helloString = "我們一起飛"
(helloString as NSString).substringWithRange(NSMakeRange(2, 3))
  • 使用 Range 的寫法
let startIndex = helloString.startIndex.advancedBy(0)
let endIndex = helloString.endIndex.advancedBy(-1)

helloString.substringWithRange(startIndex..<endIndex)

六、集合

數組

  • 數組使用 [] 定義,這一點與 OC 相同
//: [Int]
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  • 遍歷
for num in numbers {
    print(num)
}
  • 通過下標獲取指定項內容
let num1 = numbers[0]
let num2 = numbers[1]
  • 可變&不可變
    • let 定義不可變數組
    • var 定義可變數組
let array = ["zhangsan", "lisi"]
//: 不能向不可變數組中追加內容
//array.append("wangwu")
var array1 = ["zhangsan", "lisi"]

//: 向可變數組中追加內容
array1.append("wangwu")
  • 數組的類型
    • 如果初始化時,所有內容類型一致,擇數組中保存的是該類型的內容
    • 如果初始化時,所有內容類型不一致,擇數組中保存的是 NSObject
//: array1 僅允許追加 String 類型的值
//array1.append(18)

var array2 = ["zhangsan", 18]
//: 在 Swift 中,數字可以直接添加到集合,不需要再轉換成 `NSNumber`
array2.append(100)
//: 在 Swift 中,如果將結構體對象添加到集合,仍然需要轉換成 `NSValue`
array2.append(NSValue(CGPoint: CGPoint(x: 10, y: 10)))
  • 數組的定義和實例化
    • 使用 : 可以只定義數組的類型
    • 實例化之前不允許添加值
    • 使用 [類型]() 可以實例化一個空的數組
var array3: [String]
//: 實例化之前不允許添加值
//array3.append("laowang")
//: 實例化一個空的數組
array3 = [String]()
array3.append("laowang")
  • 數組的合並
    • 必須是相同類型的數組才能夠合並
    • 開發中,通常數組中保存的對象類型都是一樣的!
array3 += array1

//: 必須是相同類型的數組才能夠合並,以下兩句代碼都是不允許的
//array3 += array2
//array2 += array3
  • 數組的刪除
//: 刪除指定位置的元素
array3.removeAtIndex(3)
//: 清空數組
array3.removeAll()
  • 內存分配
    • 如果向數組中追加元素,超過了容量,會直接在現有容量基礎上 * 2
var list = [Int]()

for i in 0...16 {
    list.append(i)
    print("添加 \(i) 容量 \(list.capacity)")
}

字典

  • 定義
    • 同樣使用 [] 定義字典
    • let 不可變字典
    • var 可變字典
    • [String : NSObject] 是最常用的字典類型
//: [String : NSObject] 是最常用的字典類型
var dict = ["name": "zhangsan", "age": 18]
  • 賦值
    • 賦值直接使用 dict[key] = value 格式
    • 如果 key 不存在,會設置新值
    • 如果 key 存在,會覆蓋現有值
//: * 如果 key 不存在,會設置新值
dict["title"] = "boss"
//: * 如果 key 存在,會覆蓋現有值
dict["name"] = "lisi"
dict
  • 遍歷
    • kv 可以隨便寫
    • 前面的是 key
    • 後面的是 value
//: 遍歷
for (k, v) in dict {
    print("\(k) ~~~ \(v)")
}
  • 合並字典
    • 如果 key 不存在,會建立新值,否則會覆蓋現有值
//: 合並字典
var dict1 = [String: NSObject]()
dict1["nickname"] = "大老虎"
dict1["age"] = 100

//: 如果 key 不存在,會建立新值,否則會覆蓋現有值
for (k, v) in dict1 {
    dict[k] = v
}
print(dict)

Ubuntu 15.10安裝部署Swift開發環境 http://www.linuxidc.com/Linux/2016-01/126995.htm

Swift 的變化:從 2.2 到 3.0 會帶來什麼 http://www.linuxidc.com/Linux/2015-12/126440.htm

Swift 正式開源,同時開源 Swfit 核心庫和包管理器 http://www.linuxidc.com/Linux/2015-12/125847.htm

Apple Swift學習教程 http://www.linuxidc.com/Linux/2014-09/106420.htm

使用 Swift 構建一個 iOS 的郵件應用 http://www.linuxidc.com/Linux/2014-08/105542.htm

Swift 2.0開源化 http://www.linuxidc.com/Linux/2015-06/118594.htm

Linux下搭建Swift語言開發學習環境 http://www.linuxidc.com/Linux/2015-12/125983.htm

Swift 的詳細介紹:請點這裡

Copyright © Linux教程網 All Rights Reserved