Swift基本語法
?
簡介
1.什么是Swift
Swift是蘋果于2014年WWDC(蘋果開發者大會)發布的全新編程語言
Swift在天朝譯為“雨燕”
跟Objective-C一樣,可以用于開發iOS、Mac應用程序
蘋果從2010年7月開始設計Swift語言,耗時4年打造
?
2.Swift的語法特點
從它的語法中能看到Objective-C、JavaScript、Python等語言的影子
語法簡單、代碼簡潔、使用方便
可與Objective-C混合使用(相互調用)
?
3.為什么要設計Swift語言
讓應用開發更簡單、更快、更穩定
確保最終應用有著更好的質量
?
編程語言對比
腳本語言(比如Python)
通常易于編寫和測試,不需要經歷編譯-鏈接-運行三個繁瑣的步驟
但并不是非常強大,難以帶來高質量程序
如果你希望編寫一款游戲,完全利用設備的性能,那么這樣的語言并不理想
?
傳統編程語言(比如Objective-C)
使開發者能更好地利用設備的性能,開發更復雜的應用
但通常較難掌握,在編譯和測試時也更麻煩(經歷編譯-鏈接-運行三個步驟)
?
Swift
借鑒了Objective-C、JavaScript、Python等語言的優點
目標:簡單、高效、強大
?
相關數據
Xcode版本必須 >= 6.0,才能使用Swift進行調試和開發
?
Swift自從發布之后,備受開發者關注,1天的時間內
Xcode 6 beta下載量突破1400萬次
官方發布的電子書《The Swift Programming Language》下載量突破37萬次
一位國外開發者已經用Swift實現了Flappy Bird游戲(這位開發者上手Swift的時間只有4個小時,編程加上休息時間,接近9個小時)
?
語法須知
2個不需要
不需要編寫main函數:全局作用域中的代碼會被自動當做程序的入口點(從上往下執行)
不需要在每一條語句后面加上分號 ? ?
let radius = 10
你喜歡的話,也可以加上? ? let radius = 10;
有一種情況必須加分號:同一行代碼上有多條語句時
let radius = 10;? ? let radius2 = 15
?
注釋
單行注釋// 這是單行注釋
多行注釋 /* 這是多行注釋 */?
跟其他語言不太一樣的是,Swift的多行注釋可以嵌套多行注釋
/* haha /* hehe */ haha */
?
常量和變量
如何聲明常量和變量
用let來聲明常量
let radius = 10
?
用var來聲明變量
var age = 20
var x = 0.0, y = 0.0, z = 0.0
?
常量和變量的命名
基本上可以用任何你喜歡的字符作為常量和變量名
let π = 3.14159
let網址 = "http://ios.itcast.cn"
let?? = "dogcow"
// ?和?是一種特殊的Unicode字符
?
常量和變量名的注意點
不能包含數學符號(比如 + 和 * )
不能包含箭頭(比如↑、↓、←、→)
不能包含非法無效的Unicode字符(比如? 、?)
不能是關鍵字(比如let、var)
不能包含橫線 – 、 制表符(比如 my–name)
不能以數字開頭(比如 123go)
不能是單獨一個下劃線 _ (比如var_ = 10)
?
數據類型
Swift中常用的數據類型有
Int、Float、Double、Bool
String、Character、Array、Dictionary
可以看出,數據類型的首字母都是大寫的
?
如何指定變量\常量的數據類型
在常量\變量名后面加上“冒號:” 和 “類型名稱”
var age : Int = 10
上面代碼表示:定義了一個Int類型的變量age,初始值是10
?
一般來說,沒有必要明確指定變量\常量的類型
如果在聲明常量\變量時賦了初始值,Swift可以推斷出這個常量\變量的類型
var age = 20// Swift會推斷出age是Int類型,因為20是個整數
?
整數
整數分為2種類型
有符號(signed):正、負、零
無符號(unsigned):正、零
?
Swift提供了8、16、32、64位的有符號和無符號整數,比如
UInt8 :8位無符號整型
Int32 :32位有符號整型
?
整數的最值
可以通過min和max屬性來獲取這個類型的最小值和最大值
let minValue = UInt8.min? // UInt8 類型的 minValue 等于0
let maxValue = UInt8.max? // UInt8 類型的 maxValue 等于255
?
Int和UInt
Swift提供了特殊的有符號整數類型Int和無符號整數類型UInt
Int\UInt的長度和當前系統平臺一樣
在32位系統平臺上,Int和UInt的長度是32位
在64位系統平臺上,Int和UInt的長度是64位
Int在32位系統平臺的取值范圍:-2147483648 ~ 2147483647
?
建議
在定義變量時,別總是在考慮有無符號、數據長度的問題
盡量使用Int,這樣可以保證代碼的簡潔、可復用性
?
存儲范圍
每種數據類型都有各自的存儲范圍
Int8的存儲范圍是:–128 ~ 127
UInt8的存儲范圍是:0 ~ 255
?
如果數值超過了存儲范圍,編譯器會直接報錯
下面的語句都會直接報錯
let num1 : UInt8 = -1
// UInt8不能存儲負數
let num2 : Int8 = Int8.max + 1
// Int8能存儲的最大值是Int8.max
?
整數的表示形式
整數的4種表示形式
十進制數:沒有前綴
var i1 = 10 // 10
?
二進制數:以0b為前綴
var i2 = 0b1010 // 10
?
八進制數:以0o為前綴
var i3 = 0o12 // 10
?
十六進制數:以0x為前綴
var i4 = 0xA // 10
?
類型別名
可以使用typealias關鍵字定義類型的別名,跟C語言的typedef作用類似
typealias MyInt = Int
// 給Int類型起了個別名叫做MyInt
?
原類型名稱能用在什么地方,別名就能用在什么地方
聲明變量類型
var num : MyInt = 20
?
獲得類型的最值
var minValue = MyInt.min
?
類型轉換
var num2 = MyInt(3.14) // 3
?
浮點數
浮點數,就是小數。Swift提供了兩種浮點數類型
Double :64位浮點數,當浮點值非常大或需要非常精確時使用此類型
Float :32位浮點數,當浮點值不需要使用Double的時候使用此類型
?
精確程度
Double :至少15位小數
Float :至少6位小數
?
如果沒有明確說明類型,浮點數默認就是Double類型
let num = 0.14// num是Double類型的常量
?
浮點數的表示形式
浮點數可以用 十進制 和 十六進制 2種進制來表示
十進制(沒有前綴)
沒有指數:var d1 = 12.5
有指數? ? :var d2 = 0.125e2 ?
// 0.125e2 == 0.125 * 102
MeN ==? M * 10的N次方
?
十六進制(以0x為前綴,且一定要有指數)
var d3 = 0xC.8p0?
// 0xC.8p0 == 0xC.8 * 2o == 12.5 * 1
0xMpN == 0xM * 2的N次方
var d3 = 0xC.8p1?
?
數字格式
數字可以增加額外的格式,使它們更容易閱讀
可以增加額外的零 0
let money = 001999// 1999
let money2 = 001999.000// 1999.0
?
可以增加額外的下劃線 _ ,以增強可讀性
let oneMillion1 = 1_000_000// 1000000
let oneMillion2 = 100_0000// 1000000
let overOneMillion = 1_000_000.000_001// 1000000.000001
?
增加了額外的零? 0和下劃線 _ ,并不會影響原來的數值大小
?
類型轉換
下面的語句是錯誤的
let num1 = 3// num1是Int類型
let num2 = 0.14// num2是Double類型
let sum = num1 + num2 // 這行會報錯
// 只有將num1轉為Double類型,才能與num2進行相加
?
下面的語句是正確的
let sum = Double(num1) + num2
?
注意
下面的寫法是正確的
let sum = 3 + 0.14
// 等3和0.14相加得到結果3.14后,編譯器才會自動推斷出sum是Double類型
?
字符串
字符串是String類型的數據,用雙引號""包住文字內容
var website = "http://ios.itcast.cn"
?
字符串的常見操作
用加號 + 做字符串拼接
var scheme = "http://"
var path = "ios.itcast.cn"
var website = scheme + path
// website的內容是"http://ios.itcast.cn"
?
用反斜線 \ 和 小括號 () 做字符串插值(把常量\變量插入到字符串中)
let hand = 2
var age = 20
var str = "我今年\(age)歲了,有\(hand)只手"
// str的內容是"我今年20歲了,有2只手"
?
打印輸出
Swift提供了2個打印輸出函數
println :輸出內容后會自動換行
print :對比println,少了個自動換行的功能
?
示例
輸出字符串
println("歡迎學習傳智播客iOS學院Swift教程")
var name = "傳智播客iOS學院\n"
print(name)
?
輸出其他數據類型
var age = 7
println(age)
println("我今年\(age)歲")
?
元組類型
什么元組類型
元組類型由 N個 任意類型的數據組成(N>=0)
組成元組類型的數據可以稱為“元素”
var position = (x : 10.5, y : 20)?
// position有2個元素,x、y是元素的名稱
var person = (name : "jack") // person只有name一個元素
?
元素的訪問
用元素名稱
position.x
position.y
?
用元素位置
position.0? // 相當于postion.x
position.1? // 相當于postion.y
?
元組類型的細節
可以省略元素名稱
var position = (10, 20)
var person = (20, "jack")
?
可以明確指定元素的類型
var person : (Int, String) = (23, "rose")
注意o
在明確指定元素類型的情況下不能加上元素名稱
因此,下面的語句是錯誤的
var person : (Int, String) = (age : 23, name : "rose")
?
可以用多個變量接收元組數據
var (x , y) = (10, 20) // x是10,y是20
var point = (x, y) // point由2個元素組成,分別是10和20
?
元組類型的細節
可以將元素分別賦值給多個變量
var point = (10, 20)
var (x , y) = point
// x是10,y是20
?
可以使用下劃線 _ 忽略某個元素的值,取出其他元素的值
var person = (20, "jack")
var (_, name) = person
// name的內容是“jack”,person中的元素20被忽略
?
可選類型
可選類型的使用場合
當一個值可能存在,可能不存在的時候,就用可選類型
比如查找字符k在某個字符串中的位置
如果字符串是"jake",說明k的位置存在,是2
如果字符串是"kate",說明k的位置存在,是0
如果字符串是"itcast",說明k的位置不存在
那么k的位置就應該用可選類型
?
可選類型的格式:類型名?
var kIndex : Int?
問號?表明kIndex的值是可選的,可能是一個Int,也可能值不存在
kIndex的值要么是Int類型,要么是nil(nil代表值不存在)
kIndex默認就是nil,因此上面的語句相當于
var kIndex : Int? = nil
?
可選類型的應用
String有個toInt方法,可以將字符串轉為對應的整數
有些字符串能轉成整數,比如"156",可以返回156
有些字符串不能轉成整數,比如"itcast",無法返回整數
因此toInt方法的返回值是一個可選的Int類型(即Int?)
字符串能轉成整數,比如"156",就返回156
字符串不能轉成整數,比如"itcast",說明返回的整數值不存在,是nil
let num = "156".toInt() // 156
let num2 = "itcast".toInt() // nil
注意:num和num2都是Int?類型,不是Int類型
?
?
可選類型的注意
注意
不能直接將可選類型賦值給具體類型
比如不能將Int?類型直接賦值給Int類型,因為Int?都不確定有沒有整數值
下面的寫法是錯誤的
var num : Int? = 10
var numValue : Int = num // 這行會報錯
?
相反,可以直接將Int類型賦值給Int?類型
下面的寫法是正確的
var numValue : Int = 20
var num : Int? = numValue?
?
強制解包
在可選類型的后面加個感嘆號!,就可以把可選類型的值取出來,賦值給具體類型
下面的寫法是正確的
var num : Int? = 10
var numValue : Int = num!
// 將num中的值取出來,賦值給numValue
感嘆號!的意思是告訴編譯器:我確定可選類型里面有值,可以將值取出來了
?
基本概念
解包:將可選類型的值取出來
強制解包:使用感嘆號!將可選類型的值取出來
?
?
強制解包的注意
注意
如果可選類型的值不存在,仍然進行強制解包,會報一個錯誤
fatal error: Can't unwrap Optional.None
?
下面的代碼是錯誤的
var num : Int?
var numValue = num! // 這行會報錯
?
因此:在進行強制解包之前,一定要先檢測可選類型的值是否存在
?
?
可選類型和if
可以使用if語句來檢測一個可選類型的值是否存在
如果值存在,就返回true
如果值不存在,就返回false
let num = "156".toInt()
ifnum {
? ? println("num的值是\(num!)")
} else {
? ? println("num的值不存在")
}
?
可選類型的價值
可選類型讓開發人員可以在程序運行時,檢測一個值是否存在
然后使用代碼來分別處理存在和不存在的情況
?
選擇綁定
選擇綁定的作用
用來確定一個可選類型的值是否存在
如果值存在,把該值賦給一個臨時常量\變量
如果值不存在,就不創建任何臨時常量\變量
?
選擇綁定的概念
可選類型的值有選擇地賦給臨時常量\變量
也可以稱為“選擇綁定解包”
?
選擇綁定的使用場合
if\while語句
?
選擇綁定的應用
iflet num = "156".toInt() {
? ? println("num的值存在,是\(num)")
} else {
? ? println("num的值不存在")
}
如果"156".toInt()的值存在
就把值賦給臨時常量num,執行第1 ~ 3行的大括號之間的代碼
如果"156".toInt()的值不存在
就不創建臨時常量num,執行第3 ~ 5行的大括號之間的代碼
注意
這里的num是Int類型,不是Int?類型
num的作用域是第1~3行的大括號之間,不能用在第3~5行的大括號之間
也可以用臨時變量來存儲
ifvar num = "156".toInt() {?
} else { }
?
?
隱式解包
默認情況下:如果想將可選類型的值賦給具體類型,比如將Int?的值賦給Int類型,需要使用感嘆號!進行強制解包
var num : Int? = 10
var numValue : Int = num!
?
被聲明為隱式解包的可選類型
不用進行強制解包
能夠自動解包:自動把可選類型的值取出來賦給具體類型
?
如何聲明一個隱式解包的可選類型
將 問號? 改為 感嘆號! 即可
var num : Int! = 20
var numValue : Int = num// 自動解包,不用再使用 ! 進行強制解包
// num是被聲明為隱式解包的可選類型Int!
?
隱式解包的原理和應用
隱式解包的原理
相當于告訴編譯器:這個可選類型的值一直都存在,絕對能取出里面的值
所以取值時可以不用加感嘆號!,能夠自動解包
?
隱式解包的應用
如果某個常量\變量的值,在有些情況下一定存在,就可以用隱式解包
比如銀行卡的余額就可以聲明為隱式解包的可選類型
只要開通了銀行卡,銀行卡的余額肯定有值,從0 ~ 無限大
如果沒開通銀行卡或者銀行卡丟了,銀行卡的余額就沒有值,因為連卡都沒有
?
?
斷言
斷言是一種實時檢測條件是否為true的方法
如果條件為true,那么代碼繼續執行
如果條件為false,就拋出錯誤信息,直接終止程序的運行
?
斷言的用法
使用全局的assert函數
assert函數接收一個Bool表達式和一個斷言失敗時顯示的消息
assert(index >= 0, "index必須大于0")
如果index大于等于0,就繼續執行后面的代碼
如果index小于0,就拋出錯誤信息(下面的黑色字),直接終止程序的運行
assertion failed: index必須大于0
?
assert(index >= 0)
可以省略錯誤信息,但不推薦,這樣不利于調試
?