版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2017.07.27 |
前言
我是swift2.0的時(shí)候開始接觸的,記得那時(shí)候還不是很穩(wěn)定疾瓮,公司的項(xiàng)目也都是用oc做的脖镀,并不對(duì)swift很重視,我自己學(xué)了一段時(shí)間狼电,到現(xiàn)在swift3.0+已經(jīng)出來(lái)了蜒灰,自己平時(shí)也不寫,忘記的也差不多了肩碟,正好項(xiàng)目這段時(shí)間已經(jīng)上線了强窖,不是很忙,我就可以每天總結(jié)一點(diǎn)了削祈,希望對(duì)自己對(duì)大家有所幫助脑漫。在總結(jié)的時(shí)候我會(huì)對(duì)比oc進(jìn)行說明,有代碼的我會(huì)給出相關(guān)比對(duì)代碼咙崎。
1. swift簡(jiǎn)單總結(jié)(一)—— 數(shù)據(jù)簡(jiǎn)單值和類型轉(zhuǎn)換
2. swift簡(jiǎn)單總結(jié)(二)—— 簡(jiǎn)單值和控制流
3. swift簡(jiǎn)單總結(jié)(三)—— 循環(huán)控制和函數(shù)
4. swift簡(jiǎn)單總結(jié)(四)—— 函數(shù)和類
5. swift簡(jiǎn)單總結(jié)(五)—— 枚舉和結(jié)構(gòu)體
6. swift簡(jiǎn)單總結(jié)(六)—— 協(xié)議擴(kuò)展與泛型
7. swift簡(jiǎn)單總結(jié)(七)—— 數(shù)據(jù)類型
8. swift簡(jiǎn)單總結(jié)(八)—— 別名优幸、布爾值與元組
9. swift簡(jiǎn)單總結(jié)(九)—— 可選值和斷言
10. swift簡(jiǎn)單總結(jié)(十)—— 運(yùn)算符
11. swift簡(jiǎn)單總結(jié)(十一)—— 字符串和字符
12. swift簡(jiǎn)單總結(jié)(十二)—— 集合類型之?dāng)?shù)組
13. swift簡(jiǎn)單總結(jié)(十三)—— 集合類型之字典
14. swift簡(jiǎn)單總結(jié)(十四)—— 控制流
15. swift簡(jiǎn)單總結(jié)(十五)—— 控制轉(zhuǎn)移語(yǔ)句
函數(shù) - Functions
函數(shù)是swift
的重點(diǎn),函數(shù)用來(lái)完成特定任務(wù)的獨(dú)立的代碼塊褪猛,可以給一個(gè)函數(shù)起一個(gè)名字网杆,當(dāng)函數(shù)執(zhí)行的時(shí)候撼玄,這個(gè)名字就會(huì)被“調(diào)用”陨闹。swift
的函數(shù)風(fēng)格很靈活,可以像C
風(fēng)格的參數(shù)歇拆,也可以像OC
風(fēng)格的參數(shù)新啼,參數(shù)可以提供默認(rèn)值追城,簡(jiǎn)化函數(shù)調(diào)用,參數(shù)也可以既當(dāng)做傳入?yún)?shù)燥撞,也可以當(dāng)做傳出參數(shù)座柱,也可以說,一旦函數(shù)執(zhí)行結(jié)束物舒,傳入的參數(shù)值可以被修改色洞。
在swift
中,每個(gè)函數(shù)都有一個(gè)類型冠胯,包括函數(shù)的參數(shù)值類型和返回值類型火诸,你可以把函數(shù)類型當(dāng)做任何其他普通變量類型一樣處理,這樣可以簡(jiǎn)單的把函數(shù)當(dāng)做別的函數(shù)的參數(shù)荠察,也可以從其他函數(shù)中返回函數(shù)置蜀,函數(shù)的定義可以寫在其他函數(shù)定義中,這樣可以在嵌套函數(shù)范圍內(nèi)實(shí)現(xiàn)功能封裝悉盆。
下面主要講下面幾個(gè)大問題:
- 函數(shù)的定義與調(diào)用
(Defining and Calling Functions)
- 函數(shù)參數(shù)與返回值
(Function Parameters and Return Values)
- 函數(shù)參數(shù)名稱
(Function Parameter Names)
- 函數(shù)類型
(Function Types)
- 函數(shù)嵌套
(Nested Functions)
函數(shù)定義與調(diào)用 - Defining and Calling Functions
定義一個(gè)函數(shù)時(shí)盯荤,可以定義一個(gè)或者多個(gè)有名稱和類型的值,作為函數(shù)的輸入焕盟,也可以定義一種類型的值作為函數(shù)執(zhí)行結(jié)束的輸出秋秤。每一個(gè)函數(shù)都有一個(gè)名字,用來(lái)描述執(zhí)行的任務(wù)脚翘,可以通過函數(shù)的名字調(diào)用函數(shù)灼卢。
下面我們就看一個(gè)簡(jiǎn)單的例子。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
print(greeting(personName: "Nana"))
}
func greeting(personName : String) -> String {
return "Hello," + personName + "!"
}
}
下面看輸出結(jié)果
Hello,Nana!
函數(shù)參數(shù)與返回值 - Function Parameters and Return Values
swift
可以有任意類型任意個(gè)數(shù)的參數(shù)堰怨,函數(shù)也可以作為參數(shù)傳入芥玉,同時(shí),swift
可以有任意類型的返回值备图,函數(shù)也可以作為返回值灿巧,也可以沒有返回值赶袄,總之,非常靈活抠藕。
1. 多重輸入?yún)?shù) - Multiple Input Parameters
函數(shù)可以有多個(gè)輸入?yún)?shù)饿肺,寫在圓括號(hào)中,用逗號(hào)分隔盾似。
下面看一個(gè)簡(jiǎn)單的程序敬辣。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
print(calculateDistance(start: 1, end: 100))
}
func calculateDistance(start : Int, end : Int) -> Int {
return end - start
}
}
下面看一下輸出結(jié)果
99
2. 無(wú)參函數(shù) - Functions Without Parameters
函數(shù)可以沒有參數(shù),這時(shí)候的函數(shù)名稱后面的圓括號(hào)里面就是空的零院。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
print(greeting())
}
func greeting() -> String {
return "Hello!"
}
}
下面看輸出結(jié)果
Hello!
3. 無(wú)返回值函數(shù) - Functions Without Return Values
函數(shù)可以沒有返回值溉跃,看下面的例子,相當(dāng)于OC
中返回類型為void
的方法告抄。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
greeting(greet: "Nancy")
}
func greeting(greet : String) {
print("Hello, " + greet)
}
}
下面看輸出結(jié)果
Hello, Nancy
注意:嚴(yán)格講撰茎,雖然沒有返回值被定義,greeting
函數(shù)依然返回了值打洼,沒有定義返回類型的函數(shù)會(huì)返回特殊的值龄糊,叫Void
,它其實(shí)是一個(gè)空的元組(tuple)
募疮,沒有任何元素炫惩,可以寫成()
。函數(shù)就算有返回值也可以忽略不用阿浓,但是有返回值的函數(shù)必須返回一個(gè)值他嚷。
4. 多重返回值函數(shù) - Functions with Multiple Return Values
可以使用元組tuple
類型讓多個(gè)值作為一個(gè)復(fù)合值從函數(shù)中返回,下面看一個(gè)簡(jiǎn)單例子芭毙。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
let number = count(string: "swift is very interesting !")
print(number.vowels)
print(number.consonants)
print(number.others)
}
func count(string : String) ->(vowels : Int, consonants : Int, others : Int) {
var vowels = 0, consonants = 0, others = 0
for character in string.characters {
switch String(character).lowercased() {
case "a", "e", "i", "o", "u":
vowels += 1
case "b", "c", "d", "f", "g","h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
consonants += 1
default:
others += 1
}
}
return(vowels, consonants, others)
}
}
下面看輸出結(jié)果
7
15
5
函數(shù)參數(shù)名稱 - Function Parameter Names
函數(shù)的參數(shù)一般都這么定義:參數(shù)名(parameter name)
這些參數(shù)只能在函數(shù)體內(nèi)部使用爸舒,不能在調(diào)用函數(shù)時(shí)使用,這種類型的參數(shù)名稱被稱為局部參數(shù)名(local parameter)
稿蹲。
1. 外部參數(shù)名 - External Parameter Names
有時(shí)候,調(diào)用函數(shù)時(shí)鹊奖,給每個(gè)參數(shù)命名是非常有用的苛聘,因?yàn)檫@些參數(shù)名可以指出各個(gè)實(shí)參的用途,如果你希望函數(shù)的使用者在調(diào)用函數(shù)時(shí)提供參數(shù)名字忠聚,那就需要給每個(gè)參數(shù)除了局部參數(shù)名外再定義一個(gè)外部參數(shù)名
设哗,外部參數(shù)名寫在局部參數(shù)名之前,用空格分開两蟀。還有幾點(diǎn)要注意:
- 如果你提供了外部參數(shù)名网梢,那么函數(shù)被調(diào)用時(shí),必須使用外部參數(shù)名赂毯。
- 當(dāng)其他人讀你的代碼战虏,函數(shù)參數(shù)意圖不是很明顯時(shí)拣宰,考慮使用外部參數(shù)名,如果函數(shù)參數(shù)名的意圖很清晰就不需要定義外部參數(shù)了烦感。
下面看一個(gè)簡(jiǎn)單代碼巡社。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
print(join(string: "Hello", toString: "world", withJoiner: "-"))
}
func join(string s1 : String, toString s2 : String, withJoiner joiner : String) -> String{
return s1 + joiner + s2
}
}
下面看輸出結(jié)果
Hello-world
2. 簡(jiǎn)寫外部參數(shù)名 - shorthand External Parameter Names
如果你需要提供外部參數(shù)名,但是局部參數(shù)名已經(jīng)寫好了手趣,那么不用再修改了晌该,你可以只寫一次參數(shù)名,并用#
作為前綴绿渣,就表明這個(gè)參數(shù)可以作為局部參數(shù)名和外部參數(shù)名朝群。
注意:上面是swift 3.0
以前的功能,3.0以后已經(jīng)被去掉了中符,這里還加上這個(gè)選項(xiàng)姜胖,是讓大家區(qū)別一下。
3. 默認(rèn)參數(shù)值 - Default Parameter Values
你可以在函數(shù)體內(nèi)為每個(gè)參數(shù)定義默認(rèn)值舟茶,默認(rèn)值被定義后谭期,調(diào)用這個(gè)函數(shù)時(shí)可以忽略這個(gè)參數(shù)。下面看這個(gè)簡(jiǎn)單例子吧凉。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
print(join(string: "Hello", toString: "World", withJoiner: "-"))
print(join(string: "Hello", toString: "World"))
}
func join(string s1 : String, toString s2 : String, withJoiner joiner : String = "&&") -> String{
return s1 + joiner + s2
}
}
下面看輸出結(jié)果
Hello-World
Hello&&World
可以發(fā)現(xiàn):
- 如果參數(shù)有默認(rèn)值隧出,調(diào)用如果傳值就用我們傳入的值,但是如果調(diào)用不傳值就用參數(shù)的默認(rèn)值阀捅。
- 將帶有默認(rèn)值的參數(shù)放在函數(shù)參數(shù)列表的最后面胀瞪,這樣可以保證函數(shù)調(diào)用時(shí)候,非默認(rèn)參數(shù)的順序是一致的饲鄙,同時(shí)可以清晰的看見相同的函數(shù)在不同情況下調(diào)用時(shí)顯的更為清晰凄诞。
4. 默認(rèn)值參數(shù)的外部參數(shù)名- External Names for Parameters with Default
當(dāng)你沒有給帶默認(rèn)值的參數(shù)提供外部參數(shù)名時(shí),swift
會(huì)自動(dòng)提供外部名字忍级,函數(shù)調(diào)用的時(shí)候帆谍,外部參數(shù)名必須使用。下面看例子轴咱。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
print(join(string: "Hello", toString: "World", withJoiner: " - "))
}
func join(string : String, toString : String, withJoiner : String = "&&") -> String{
return string + withJoiner + toString
}
}
下面看輸出結(jié)果
Hello - World
注意:你也可以使用下劃線_
作為默認(rèn)值參數(shù)的外部參數(shù)名汛蝙,這樣可以在調(diào)用時(shí)不用提供外部參數(shù)名,但是給帶默認(rèn)值參數(shù)命名總是更加合適的朴肺。
5. 可變參數(shù) - Variadic Parameters
一個(gè)可變參數(shù)可以接受一個(gè)或多個(gè)值窖剑,函數(shù)調(diào)用時(shí),你可以用可變參數(shù)來(lái)傳入不確定數(shù)量的輸入?yún)?shù)戈稿,通過在變量類型后面加上...
的方式定義可變參數(shù)西土。
下面我們看一個(gè)例子。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
print(sum(numbers: 1, 3, 4))
print(sum(numbers: 100, 300, 500))
}
func sum(numbers : Double...) -> Double{
var total = 0.0
for number in numbers {
total += number
}
return total
}
}
下面看輸出結(jié)果
8.0
900.0
還有幾點(diǎn)要注意:
- 傳入函數(shù)的參數(shù)被當(dāng)做這個(gè)類型的一個(gè)數(shù)組處理鞍盗。
- 一個(gè)函數(shù)最多只能有一個(gè)可變參數(shù)需了,而且它必須是參數(shù)表中最后的一個(gè)跳昼,這樣做的目的是為了避免函數(shù)調(diào)用出現(xiàn)歧義。
- 如果一個(gè)函數(shù)有一個(gè)或者多個(gè)帶默認(rèn)值的參數(shù)援所,而且還有一個(gè)可變參數(shù)庐舟,那么把可變參數(shù)放在參數(shù)表的最后。
6. 常量參數(shù)和變量參數(shù) - Constant and Variable Parameter
函數(shù)參數(shù)默認(rèn)是常量住拭,在函數(shù)體內(nèi)改變參數(shù)值會(huì)報(bào)錯(cuò)挪略,但是有的時(shí)候有傳入?yún)?shù)的變量值副本是很有用的,你可以通過指定一個(gè)或者多個(gè)參數(shù)為變量函數(shù)滔岳,從而避免自己在函數(shù)中定義新的變量杠娱,變量參數(shù)不是常量,你可以在函數(shù)體內(nèi)部把它當(dāng)做新的可修改副本來(lái)使用谱煤。
常量參數(shù)變?yōu)樽兞繀?shù)的方法就是在參數(shù)名前面加關(guān)鍵字var
摊求,說了這么多上面都是swift 3.0
以前的寫法,那么swift 3.0
以后怎么寫呢刘离,看下面的例子室叉。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
var number = 10
print(sum(number: &number, number2: 20))
}
func sum(number : inout Int, number2 : Int) -> Int {
number += number2
return number
}
}
下面看輸出結(jié)果
30
可以看見,現(xiàn)在不用var
而是用inout
了硫惕,這里需要注意的就是inout
的位置茧痕。
7. 輸入輸出函數(shù) - InOut Parameters
有的時(shí)候我們想要一個(gè)函數(shù)可以修改參數(shù)的值,并且當(dāng)函數(shù)調(diào)用結(jié)束后恼除,這個(gè)參數(shù)仍可用踪旷,這個(gè)時(shí)候我們就要把這個(gè)參數(shù)定義為輸入輸出參數(shù)- In - Out Parameters
。定義輸入輸出參數(shù)豁辉,需要在參數(shù)定義前加一個(gè)inout
關(guān)鍵字令野,一個(gè)輸入輸出參數(shù)有傳入函數(shù)的值,這個(gè)值被函數(shù)修改徽级,然后被傳出函數(shù)气破,替換原來(lái)的值。
下面看一個(gè)簡(jiǎn)單的例子餐抢。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
var number1 = 10
var number2 = 20
swap(&number1, &number2)
print(number1)
print(number2)
}
func swapNumbers(a : inout Int, b : inout Int){
let temp = a
a = b
b = temp
}
}
下面看輸出結(jié)果
20
10
這里大家要注意inout
的位置堵幽,放在類型說明之前,冒號(hào)之后弹澎。
函數(shù)類型
每一個(gè)函數(shù)都有函數(shù)類型,由函數(shù)參數(shù)類型和返回值類型組成努咐。例如(Int, Int) -> Int
它的意義就是:這個(gè)函數(shù)類型是苦蒿,它有兩個(gè)Int
型的參數(shù),并返回一個(gè)Int
型的值渗稍。
下面我們看幾種情況佩迟。
1. 使用函數(shù)類型 - Using Function Types
在swift
中团滥,使用函數(shù)類型就像使用其他類型一樣,例如你可以定義一個(gè)類型為函數(shù)的常量或者變量报强,并將函數(shù)賦值給它灸姊。
var mathFunction = (Int, Int) -> Int = addInts
上面這個(gè)讀作:定義一個(gè)叫做mathFunction
的變量,類型是一個(gè)有兩個(gè)Int
型的參數(shù)并返回一個(gè)Int
型的值的函數(shù)秉溉,并將這個(gè)新變量指向addInts
函數(shù)力惯。
有了這個(gè)定義,以后你可以使用mathFunction
調(diào)用被賦值的函數(shù)了召嘶,比如:
mathFunction(2, 3)
有相同類型的不同函數(shù)可以被賦值給同一個(gè)變量父晶,就像非函數(shù)類型的變量一樣,比如:
mathFunction = multiplyTwoInts
這里multiplyTwoInts
和addInts
函數(shù)類型是相同的弄跌。
像其他數(shù)據(jù)類型一樣甲喝,當(dāng)賦值一個(gè)函數(shù)給常量或者變量的時(shí),swift
用來(lái)推斷其函數(shù)類型铛只。
let anotherMathFunction = addInts
這里anotherMathFunction類型也被推斷為 (Int, Int) -> Int埠胖。
2. 函數(shù)類型作為參數(shù)類型 - Function Types as Parameter Types
這里函數(shù)類型作為參數(shù)類型并不傳入函數(shù)是如何實(shí)現(xiàn)的,它只關(guān)心這個(gè)傳入的函數(shù)類型是否正確淳玩,下面看一個(gè)簡(jiǎn)單的例子直撤。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
multiply(sum: sum, a: 1, b: 2)
}
func multiply(sum : (Int, Int) -> Int, a : Int, b : Int) {
let result = sum(a, b) * a * b
print("result = \(result)")
}
func sum(a : Int, b : Int) -> Int {
return a + b
}
}
下面看輸出結(jié)果
result = 6
3. 函數(shù)作為返回類型 - Functions Type as Return Types
你可以用函數(shù)類型作為另一個(gè)函數(shù)的返回類型,你需要做的是在返回箭頭->
后寫一個(gè)完整的函數(shù)類型凯肋。
可以看下面這個(gè)例子谊惭。
class JJSwiftVC: UIViewController
{
var currentValue = 10;
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
while currentValue > 0 {
let moveToZero = chooseStepFunction(input: currentValue > 0)
var result = moveToZero(currentValue)
print(result)
currentValue -= 1
}
}
func chooseStepFunction(input : Bool) -> (Int) -> Int {
if input {
return backForward
}
else {
return stepForward
}
}
func stepForward(input : Int) -> Int {
return input + 1
}
func backForward(input : Int) -> Int {
return input - 1
}
}
下面看輸出結(jié)果
9
8
7
6
5
4
3
2
1
0
嵌套函數(shù) - Nested Functions
前面介紹的函數(shù)都是全局函數(shù),你也可以把函數(shù)定義在別的函數(shù)體中侮东,這種函數(shù)叫做嵌套函數(shù)圈盔,嵌套函數(shù)對(duì)于外界來(lái)說是不可見的,但是可以被它們封閉函數(shù)(enclosing Function)
調(diào)用悄雅,一個(gè)封閉函數(shù)也可以返回它的某一個(gè)嵌套函數(shù)驱敲,使得這個(gè)函數(shù)可以在其他域中被使用。
我們接著看一個(gè)例子宽闲。
class JJSwiftVC: UIViewController
{
var currentValue = 10;
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
while currentValue > 0 {
let moveToZero = chooseStepFunction(input: currentValue > 0)
var result = moveToZero(currentValue)
print(result)
currentValue -= 1
}
}
func chooseStepFunction(input : Bool) -> (Int) -> Int {
func stepForward(input : Int) -> Int {
return input + 1
}
func backForward(input : Int) -> Int {
return input - 1
}
if input {
return backForward
}
else {
return stepForward
}
}
}
下面看輸出結(jié)果
9
8
7
6
5
4
3
2
1
0
后記
未完众眨,待續(xù)~~~