Swift基礎語法簡化版

推薦一個學習網站:https://www.cnswift.orgphp

該網站是對Swift官方文檔的翻譯,但不是無腦翻譯,而是結合做者的開發經驗,在翻譯的基礎上,給出一些實用的建議。

常量與變量python

在Swift中規定,定義一個標識符的時候必須明確說明該標識符是常量仍是變量:swift

使用let來定義常量,定義以後不可修改;數組

使用var來定義變量,定義以後能夠修改。ruby

let a: Int = 2a = 3//會報錯,由於a是常量,不能夠修改
var b: Int = 6b = 8//正常運行,b是變量,能夠修改

基本數據類型bash

Swift中的基本數據類型包括:整型、浮點型、Bool型數據結構

整型架構

有符號整型app

Int8:有符號8位整型函數

Int16:有符號16位整型

Int32:有符號32位整型

Int64:有符號64位整型

Int:默認,和平臺相關,至關於OC中的NSInteger

無符號整型

UInt8:無符號8位整型

UInt16:無符號16位整型

UInt32:無符號32位整型

UInt64:無符號64位整型

UInt:默認,和平臺相關,至關於OC中的NSUInteger

浮點型

Float:32位浮點型

Double:64位浮點型(默認)

Bool型

true:真

false:假

基本數據類型的運算與OC是同樣的:

a+b//加
a-b//減
a*b//乘
a/b//除
a%b//取餘

a+b//加a-b//減a*b//乘a/b//除a%b//取餘可是須要注意的是,在Swift中,不一樣類型的數據是不能夠運算的,好比整型和浮點型就不能夠一塊進行運算:

若是想要運算,那麼就要將其中一種類型轉爲另外一種類型:

var c = 1var d = 1.1Double(c)+d

Swift中的類型推導

Swift是一種強類型語言,也就是說,在Swift中,任何一個變量或者常量都必須有明確的類型。

var d: Int = 8

若是在定義一個標識符的時候有直接進行賦值,那麼標識符後面 的類型能夠省略:

var d = 8

由於Swift有類型推導,會自動根據後面的賦值來決定前面的標識符的數據類型。

咱們能夠經過option+鼠標左鍵來查看變量的數據類型:

須要注意的是,若是一個變量的類型已經肯定了,那麼就不能夠再給變量賦其餘類型的值:

這裏的變量c已是整型了,那麼就只能給其賦整型值,不可賦其餘類型的值。

運算符

計算運算符

+、-、*、/、%

須要特別注意的是,計算運算符兩邊的數據類型必須爲同一類型,若是類型不一樣,則編譯器會報錯。

賦值運算符

=、+=、-=、*=、/=、%=

須要特別注意的是,賦值運算符兩邊的數據類型必須爲同一類型,若是類型不一樣,則編譯器會報錯。

比較運算符

、>=、<、<=、==、!=

須要特別注意的是,比較運算符兩邊的數據類型必須爲同一類型,若是類型不一樣,則編譯器會報錯。

區間運算符

Swift特有的。

1...8   //閉區間運算符,表示從1到8(包括1和8)的全部值的區間1...    //閉區間運算符,表示從1日後無限延伸...8    //閉區間運算符,表示從8往前無限延伸1..<8   //半開區間運算符,表示從1到8(包括1,可是不包括8)的全部值的區間..<8    //半開區間運算符,表示從8往前(不包括8)無限延伸

元組

OC中沒有元組類型,元組是Swift中特有的一種數據結構。

元組用於定義一組數據,組成元組的數據能夠稱爲元素。

咱們如今使用元組來描述一我的的信息:

var one = ("Norman", "male", 30, 178.5)print(one.0)

而後摁住option鍵單擊,發現變量one的類型以下:

這個類型是根據賦的值倒推出來的。

上面的元組one中的元素從左到右一次表示:名字、性別、年齡、身高。人們乍一看,其實仍是不知道每一個元素分別表明的意思的,因此爲了便於理解,爲了可以見文知意,咱們還能夠這樣來定義元組:

//給元組中的元素加上名稱,以後能夠經過元素名稱來訪問元素
var one = (name:"Norman", gender:"male", age:30, height:178.5)
print(one.name)

摁住option鍵單擊,發現變量one的類型以下:

元組中元素的訪問

//寫法一
let error = (404, "Not Found")
//下標訪問
print(error.0)
print(error.1)

//寫法二
let error = (errorCode:404, errorInfo:"Not Found")
//別名訪問
print(error.errorCode)
print(error.errorInfo)

邏輯分支

分支的介紹

所謂的分支語句,就是if/switch/三目運算符等判斷語句。

經過分支語句能夠控制程序的執行流程。

if分支語句

Swift中的if語句和OC中的if語句仍是有區別的:

區別1:Swift中判斷句能夠不加小括號(),可是判斷以後的執行語句必需要用大括號{}括起來;OC中判斷語句必須加小括號(),若是判斷以後的執行語句只有一句話的話能夠省略大括號{}。

let g = 8if g>0 {    print("正數")}

區別2:Swift的判斷句中必需要有明確的真假,必需要有明確的布爾值,Swift中再也不有非0即真的概念;OC中是非0即真、非空即真。

三目運算符

Swift中的三目運算與OC中保持了一致的風格。

let a = 10;let b = 20;
//打印較大值print(a > b ? a : b);

guard的使用

guard語句與if語句很是相似,可是與if語句不一樣的是,guard語句當條件爲false的時候纔會執行{}裏面的代碼

guard語句必須帶有else語句,他的語法以下:

  • 當條件表達式爲true的時候跳過else語句的內容,執行後面的語句組;
  • 當條件表達式爲false的時候執行else語句中的內容,跳轉語句通常是return、break、continue或者throw
guard 條件表達式 else {  //當條件表達式不成立的時候執行的語句  break}
語句組

另一個須要說明的點是,guard語句必須放在函數中。

func online(age : Int) -> Void {    guard age >= 18 else {        print("未成年人不能上網")        return    }    print("能夠上網")}
online(age: 17)

Switch-case語句

switch做爲選擇語句中必不可少的語句也被加入到了Swift中。

首先看一個例子:

/** case區間*/let a = 100
switch a {case ..<60:    print("不及格")case 60..<80:    print("合格")case 80..<90:    print("良好")case 90...100:    print("優秀")default:    print("天才")}
/** 一個case能夠判斷多個值,多個值以,隔開*/let b = 0
switch b {case 0,1:    print("正常人")default:    print("其餘")}
/** fallthrough關鍵字進行穿透* 所謂的穿透是指,當這個case知足的時候,執行完這個case所對應的內容以後,* 不會跳出,而是接着執行緊挨着的下一個case所對應的內容*/let c = 0
switch c {case 0:    fallthroughcase 1:    print("正常人")default:    print("其餘")}
/** switch是支持多種數據類型的* 不但支持整型、區間,還支持浮點型、字符串等。*/let d = 10let e = 5var result = 0
let opration = "+"
switch opration {case "+":    result = d + ecase "-":    result = d - ecase "*":    result = d * ecase "/":    result = d / edefault:    result = 0}

Swift中的case後面的語句塊執行完畢以後能夠不跟break,由於默認會有break。

循環

在C/OC中,常見的循環有for/while/do-while;在Swift中,對應的循環有for/while/repeat-while。

For循環

for循環分爲兩種,一種是傳統的C語言風格的for循環,以下:

for var i = 0; i < 10; i++ {    print(i)}

這種傳統寫法,在Swift3中已經被淘汰了,以下:

還有一種是for-in循環,以下:

for i in 0..<10 {    print(i)}

關於for-in循環,有一個特殊的地方須要注意:若是在某個循環中不須要用到下標i,那麼使用下劃線來代替下標,以下所示:

for _ in 0..<10 {    print("Swift")}

否則的話會有以下的警告⚠️:

while循環和repeat-while循環

//while循環(先判斷,再執行)var a = 0
while a < 10 {    print(a)    a+=1}
//repeat-while循環(先執行一次,再判斷)var a = 0
repeat {    print(a)    a += 1} while a < 0

Swift中的repeat-while循環與OC中的do-while循環其實如出一轍,均可以保證至少執行一次。

字符串

OC和Swift中的字符串是有區別的:

  • 在OC中,字符串類型是NSString;在Swift中,字符串類型是String。
  • OC中定義字符串是使用@"";Swift中定義字符串是使用""。

字符串的定義

//不可變字符串let str1 = "不可變字符串"
//可變字符串var str2 = "可變字符串"str2 = "我變變變"
//多行字符串var str3 = """多行字符串第一行第二行第三行第四行56"""

上面介紹了了幾種傳統的字符串定義形式,接下來咱們來聊聊Swift5.0以後新推出的Raw String(原始字符串)

Raw String 是使用 # 來包裹字符串,其最大的特色就是:它不會對反斜槓進行特殊的轉義處理

當字符串中含有雙引號或者反斜槓轉義符的時候,使用傳統的方式定義以下:

let var1 = "若是句子中有雙引號""就會很尷尬"//輸出:若是句子中有雙引號""就會很尷尬let var2 = "若是句子中有轉義字符就會很尷尬"//輸出:若是句子中有轉義字符就會很尷尬

使用Swift5.0新推出的RawString定義以下:

let var1 = #"若是句子中有雙引號""就會很尷尬"#let var2 = #"若是句子中有轉義字符就會很尷尬"#

若是字符串是被#包裹,那麼 是不須要轉義的

那若是字符串中有#,那怎麼辦呢?答案是使用兩個井號##來包裹:

let var1 = ##"若是句子中有井號#"##//打印結果:若是句子中有井號#

字符串的經常使用操做

//計算字符串的長度
let str = "12345678"
print(str.count)
print((str as NSString).length)

//拼接兩個字符串
var str1 = "Norman" + "Lee"
var str2 = str1.appending("666")

//遍歷字符串(字符串能夠當作是多個字符的集合)
let str = "abcdefg"
for char in str {
    print(char)
}

//字符串中是否包含某子字符串
let str = "abcdefg"
print(str.contains("abc")) //true
print(str.contains("A")) //false
print(str.contains("h")) //false

//分割字符串
let str = "abc&def&ghi&jkl&mn"
let desc = str.components(separatedBy: "&") // ["abc", "def", "ghi", "jkl", "mn"]
for item in desc {
    print(item)
}

//字符串替換
let str = "abc&def&ghi&jkl&mn"
let result = str.replacingOccurrences(of: "&", with: "---")
print(result) // abc---def---ghi---jkl---mn

數組

數組是一堆有序的由相同類型的元素構成的集合。

數組中的元素是有序的,能夠重複出現

Swift用Array表示數組,它是一個泛型集合

數組的初始化

數組分爲可變數組和不可變數組

//定義一個可變數組
var arrar1 : [String] = [String]() //此時定義的是一個空數組

//定義一個不可變數組
let array2 : [String] = ["Norman", "Lavie"]

聲明一個Array類型有以下兩種寫法,能夠任選其一:

//語法糖var array1 : [String]
var array2 : Array<String>

聲明的數組須要進行初始化才能使用,數組類型每每是在聲明的同時進行初始化的:

//定義的同時直接進行初始化
var array1 = ["Norman", "Lavie"]

//先定義,而後初始化
var array2 : Array<String> array2 = ["Norman", "Lavie"]

注意區分<u >數組和元組</u>。

數組的基本操做

var array = ["Norman", "Lavie", "緒雨成瀾"]

//獲取長度
array.count // 3

//判空
array.isEmpty // false

//尾部添加元素
array.append("大魚") // ["Norman", "Lavie", "緒雨成瀾", "大魚"]

//指定位置插入元素
array.insert("Bruce", at: 1) // ["Norman", "Bruce", "Lavie", "緒雨成瀾", "大魚"]

//刪除元素
array.remove(at: 0)
array.removeLast()
array.removeFirst()

//修改元素
array[0] = "小李"

//取值(直接經過下標索引取值)
print(array[0])
print(array[1])

//倒序
array.reverse()

數組的遍歷

var array = ["Norman", "Lavie", "緒雨成瀾", "大魚"]

//for-in遍歷下標
for i in 0..<array.count {
    print(array[i])
}

//for-in遍歷元素
for name in array {
    print(name)
}

//遍歷某區間內的元素
for name in array[0...2] {
    [print(name)]
}

//元組方式的遍歷(若是既須要拿到索引又須要拿到元素,推薦使用該方式)
for (index, name) in array.enumerated() {
    print(index)
    print(name)
}

數組的合併

var array1 = ["Norman", "Lavie"]
var array2 = ["緒雨成瀾", "大魚"]
array1 += array2
print(array1) // ["Norman", "Lavie", "緒雨成瀾", "大魚"]

雖然僅僅用一個加號就能夠實現數組的合併,可是必定要保證一點:要合併的兩個或者多個數組的元素類型必需要保持一致

字典

字典是由鍵值對(key:value)組成的集合,它由兩部分集合構成:一個是鍵集合,一個是值集合。字典是經過訪問鍵來間接訪問值的,鍵集合中是不能夠有重複元素的,而值集合中的元素是能夠重複的。

字典中的元素是無序的。

Swift中的字典類型是Dictionary,是一個泛型集合

字典的初始化

在Swift中,使用let修飾的字典是不可變字典,使用var修飾的字典是可變字典:

//定義一個可變字典
var dic1 : [String : Any] = [String : Any]()

//定義一個不可變字典
let dic2 : [String : Any] = ["name" : "Norman", "age" : 28]

在聲明一個字典的時候,有下面兩種方式,能夠任選其一:

var dic : [String : Any]
var dic : Dictionary<String, Any>

跟數組同樣,聲明的字典也是須要初始化以後才能使用:

//聲明的同時進行初始化
var dic1 : [String : Any] = [String : Any]()

//先聲明,後初始化
var dic : Dictionary<String, Any>
dic = ["name" : "Norman", "age" : 28]

額外說一點,在Swift中,任意類型是使用Any來表示的。

字典的基本操做

var dict : [String : Any] = ["name" : "Lavie", "age" : 18, "gender" : "male"]

//長度
print(dict.count)

//判空
print(dict.isEmpty)

//添加元素
dict["height"] = 178
dict["weight"] = 65

/*
 * 須要注意的是,上面添加元素的這種方式,若是Key值不存在,那麼就是添加元素;
 * 若是Key值存在,那麼就是修改元素
 */

//刪除元素
dict.removeValue(forKey: "age") // 刪除指定元素
dict.removeAll() // 刪除全部元素

//修改字典
dict["name"] = "Norman" // 方式一
dict.updateValue("大魚", forKey: "name") // 方式二

//查詢字典
print(dict["name"])

字典的遍歷

var dict : [String : Any] = ["name" : "Lavie", "age" : 18, "gender" : "male"]

//遍歷字典中全部的Value值
for value in dict.values {
    print(value)
}

//遍歷字典中全部的Key值
for key in dict.keys {
    print(key)
}

//遍歷全部的鍵值對
for (key, value) in dict {
    print(key)
    print(value)
}

字典的合併

前面講的字符串和數組,都是能夠直接使用加號+來進行合併的,可是這一點對於字典並不適用。字典是不能夠直接使用加號+來進行合併的。

字典應該使用以下方式來合併:

var dict1 : [String : Any] = ["name" : "Lavie", "age" : 18, "gender" : "male"]var dict2 : [String : Any] = ["height" : 178, "weight" : 65]for (key, value) in dict2 {    dict1[key] = value}print(dict1) // ["gender": "male", "age": 18, "weight": 65, "height": 178, "name": "Lavie"]

可是這種合併字典的方式須要特別注意,若是有Key重名,那麼該Key在原字典中所對應的Value值將被新字典中所對應的Value值覆蓋。

可選型

在OC中,若是一個變量暫時不使用,能夠賦值爲0(基本數據類型)或者賦值爲nil(對象類型)。在OC中,nil就表示一個空指針,它並不做爲一個特殊的類型。

在Swift中,nil是一個特殊的類型,它與Int、String同樣,都是一種類型。而且Swift語言又是一種強類型語言,所以不能直接將nil賦值給其餘類型的數據。

在開發中,碰到nil在所不免,所以Swift推出了可選類型。

可選類型的取值有以下兩種:

  • 無值的狀況下——nil
  • 有值的狀況下——正常取值

定義可選類型

//寫法一:官方定義方式
var a : Optional<Int> = 6 // 有值
a = nil // nil

//寫法二:語法糖(直接在類型後面加問號?)
var b : Int? = 8 // 有值
b = nil // nil

可選類型的使用

給可選類型賦值:

// 定義可選類型
var name : String? = nil

//給可選類型賦值
name = 123 // ❌錯誤寫法,可選類型也是有類型校驗的,這裏只能複製字符串,賦值其餘類型都會報錯
name = "norman" // 正確

// 打印結果
print(name) // Optional("norman")  由於是可選類型,因此會帶Optional

取出可選類型的值(顯性解包):

// 定義可選類型
var name : String? = "Norman"

print(name) // Optional("norman")

//取出可選類型的真實值
//使用!強制解包(顯性解包)
print(name!) // Norman

//若是可選類型爲nil,強制解包會出錯
name = nil
//print(name!) // 報錯:Unexpectedly found nil while unwrapping an Optional value

//正確寫法應該先判空
if name != nil {
    print(name!)
}

取出可選類型的值(隱式解包):

Swift中有一個if-let寫法,if-let就是專門用於作可選綁定(隱式解包)的,以下:

if let 常量 = 可選型 {    //處理常量}

這裏的【常量 = 可選型】語句的做用是:若是可選型的值不是nil,那麼就將可選型的真實值傳給常量,而且執行花括號{}裏面的語句;若是可選型的值是nil,那麼【常量 = 可選型】這個條件就不成立(由於不能直接給一個非可選型變量賦值爲nil),那麼就不會走到花括號裏面的內容。

// 定義可選類型
var name : String? = "Norman"

/*
 *可選綁定(隱式解包)
 */
if let nameString = name {
    print(nameString)
}

強烈推薦使用可選綁定來對可選型進行隱式解包

類型轉換

基礎數據類型轉換

好比Double轉Int,Int轉Float等,只須要使用數據類型(待轉類型)便可:

//Int轉Double
var a : Int = 6
var b : Double = Double(a)

//Float轉Int
var c : Float = 8.99
var d : Int = Int(c)

基礎類型與字符串轉換

//字符串插值能夠直接將基礎類型轉換成字符串
var age : Int = 6
var str = "小明今年(age)歲了"

//字符串轉成基本類型,必需要保證字符串的內容是能夠轉換的
var string = "123"
var d = Int(string)

函數

Swift中的函數,其實就至關於Objective-C中的方法。函數的格式以下:

func 函數名(參數,列表)  -> 返回值類型 {    代碼塊    return 返回值}

有如下幾點說明:

1,func 是定義函數的關鍵字

2,參數列表中的多個參數之間,可使用英文逗號 , 分割,也能夠沒有參數

3,使用 -> 指向返回值類型

4,若是函數沒有返回值,則 -> 返回值類型 部分能夠省略

常見的函數類型

沒有參數,沒有返回值:

//寫法一:官方標準寫法
func drinkWater() -> Void {
    print("drink water 111")
}

//寫法二:若是沒有返回值,Void能夠寫成()
func drinkWater1() -> () {
    print("drink water 222")
}

//寫法三:若是沒有返回值,後面的內容能夠都不寫
func drinkWater2() {
    print("drink water 333")
}

//調用函數
drinkWater()
drinkWater1()
drinkWater2()

有參數,沒有返回值:

func call(phoneNumber : String) {    print("加入iOS交流羣(phoneNumber)")}call(phoneNumber: "642363427")

沒有參數,有返回值:

func myName() -> String {    return "norman"}let name = myName()

有參數,有返回值:

func plus(a : Int, b : Int) -> Int {    return a + b;}let result = plus(a: 3, b: 3)

函數的使用注意

1,每個函數的形式參數都包含形式參數標籤和形式參數名兩部分

  • 形式參數標籤用在調用函數的時候
  • 形式參數名用在函數的實現當中
  • 在調用函數的時候,每個形式參數前邊都會有一個形式參數標籤
  • 默認狀況下,形式參數使用它們的形式參數名做爲形式參數標籤
  • 若是不想要形式參數標籤,能夠在形式參數名稱前加上 _
//這裏的info1和info2就是形式參數標籤
//name和age是形式參數名稱
func personalInfo(info1 name : String, info2 age : Int) {
    //在函數的實現中使用形式參數名稱
    print("姓名:(name),年齡:(age)")
}
//在函數調用的時候使用形式參數標籤
personalInfo(info1: "norman", info2: 23)

//下面是默認寫法
//此時,name和age既是形式參數標籤,也是形式參數名稱
func personalInfo(name : String, age : Int) {
    //在函數內部實現的時候,name和age是形式參數名稱
    print("姓名:(name),年齡:(age)")
}
//在函數調用的時候,name和age是形式參數標籤
personalInfo(name: "norman", age: 24)

//若是不想要形式參數標籤,能夠在形式參數名稱前面加 _
func personalInfo(_ name : String, _ age : Int) {
    print("姓名:(name),年齡:(age)")
}
//在函數調用的時候,沒有形式參數標籤
personalInfo("norman", 24)

2,能夠給函數的參數設置默認值

//若是不想要形式參數標籤,能夠在形式參數名稱前面加 _
func personalInfo(_ name : String = "lavie", _ age : Int = 28) {
    print("姓名:(name),年齡:(age)")
}

personalInfo() // 姓名:lavie,年齡:28
personalInfo("norman", 24) // 姓名:norman,年齡:24

3,指針的傳遞

默認狀況下,函數的參數是值傳遞。若是想改變外面的變量,則須要傳遞變量的地址。

//交換值
func swapInt(a : inout Int, b : inout Int) {
    let temp = a
    a = b
    b = temp
}

var a = 6
var b = 8
print("a=(a), b=(b)") // a=6, b=8
swap(&a, &b) // 將地址傳遞進來
print("a=(a), b=(b)") // a=8, b=6

函數的類型

咱們以前介紹的數組Array、字典Dictionary等,都是值類型,而函數是引用類型

每一個函數都有屬於本身的類型,一個函數的類型是由該函數的參數類型返回類型決定的。

有了函數類型之後,就能夠把函數類型像Int、Array同樣來使用了。

下面的例子定義了additionMethod和multiplicationMethod兩個函數,這兩個函數都傳入了兩個Int類型的參數,返回一個Int類型值,所以這兩個函數的類型都是(Int, Int) -> Int

func additionMethod(a : Int, b : Int) -> Int {    return a + b;}
func multiplicationMethod(a : Int, b : Int) -> Int {    return a * b;}

接下來咱們來看一下函數的簡單賦值:

//初始化一個函數類型變量,並賦初始值
var mathMethod = additionMethod
mathMethod(2, 3) // 5
//給函數類型變量賦其餘值
mathMethod = multiplicationMethod
mathMethod(2, 3) // 6

函數也能夠做爲一個函數的參數:

func additionMethod(a : Int, b : Int) -> Int {
    return a + b;
}

func multiplicationMethod(a : Int, b : Int) -> Int {
    return a * b;
}

//函數做爲參數
func printResult(a : Int, b : Int, mathMethod : (Int, Int) -> Int) {
    print(mathMethod(a, b))
}

printResult(a: 3, b: 4, mathMethod: additionMethod) // 7
printResult(a: 3, b: 4, mathMethod: multiplicationMethod) // 12

函數還能夠做爲一個函數的返回值:

func additionMethod(a : Int, b : Int) -> Int {
    return a + b;
}

func multiplicationMethod(a : Int, b : Int) -> Int {
    return a * b;
}

//函數做爲返回值
func mathMethod(a : Int) -> (Int, Int)->Int {
    if a > 10 {
        return additionMethod
    }
    return multiplicationMethod
}

var resultMethod = mathMethod(a: 11)
resultMethod(6, 8) // 14

推薦文章

相關文章
相關標籤/搜索