函數(shù)的定義,實現(xiàn)與調(diào)用
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let a = sum(x: 10, y: 20)
print(a)
let b = minus(x: 100, y: 50)
print(b)
let c = sum1(num1: 100, num2: 200)
print(c)
}
//函數(shù)定義的格式
//func 函數(shù)名(行參列表) --> 返回值類型
func sum(x:Int,y:Int) -> Int {
return x + y
}
func minus(x:Int,y:Int) -> Int {
return x - y
}
}
- 函數(shù)定義的一般格式為:
func 函數(shù)名(形參列表) -> 返回值類型 { 實現(xiàn)體 } - 函數(shù)形參默認(rèn)是let,也只能是let;
函數(shù)的外部參數(shù)
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let c = sum1(num1: 100, num2: 200)
print(c)
}
//外部參數(shù)
//外部參數(shù),不會影響到函數(shù)內(nèi)部的代碼執(zhí)行
//其作用是:告訴函數(shù)調(diào)用者,每個參數(shù)的含義
//外部參數(shù)在閉包中很重要
func sum1(num1 x:Int,num2 y:Int) -> Int {
return x + y
}
}
- 函數(shù)定義時,
num1與num2 稱之為本地參數(shù); - 函數(shù)調(diào)用時,
num1與num2 稱之為外部參數(shù); - 函數(shù)的外部參數(shù),可增強代碼的可讀性;
函數(shù)無返回值
- 函數(shù)無返回值有三種格式:
什么都不寫Void-
()可以看成是空元組
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
demo1()
demo2()
demo3()
}
//函數(shù)沒有返回值的情況
//1.什么都不寫
//2.Void
//3.()
//日常開發(fā)中,可以什么都不寫,三種格式一定要知道
//三種類型,在閉包中會使用!
func demo1() {
print("haha")
}
func demo2() -> Void {
print("hehe")
}
func demo3() -> () {
print("heihei")
}
}
- 日常開發(fā)中,可以什么都不寫,三種格式一定要知道;
- 三種類型,在閉包中會使用;
隱式返回
- 如果整個函數(shù)體是一個單一表達式,那么函數(shù)會 隱式返回 這個表達式;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(xxx(x: 10, y: 20))
}
func xxx(x:Int,y:Int) -> Int {
x * y
}
}
-
func xxx(x:Int,y:Int) -> Int:內(nèi)部實現(xiàn)省略了return;
返回元組:實現(xiàn)多個返回值
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let result = cal(x: 90, y: 30)
print(result.sum)
print(result.differ)
print(result.average)
}
func cal(x:Int,y:Int) -> (sum:Int,differ:Int,average:Int) {
let sum = x + y
return(sum,x-y,sum>>1)
}
}
- func cal(x:Int,y:Int) -> (sum:Int,differ:Int,average:Int):其返回值為
(sum:Int,differ:Int,average:Int)就是個元組,包含三個整數(shù);
參數(shù)標(biāo)簽
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
goToWork(at: "09:00")
}
func goToWork(at time:String) -> Void {
print("this time is \(time)")
}
}
- 默認(rèn)情況下,
函數(shù)的本地參數(shù)和外部參數(shù)是相同的,我們通過參數(shù)標(biāo)簽,修改外部參數(shù)的名稱; -
at是參數(shù)標(biāo)簽,它可以是的函數(shù)在外界調(diào)用時,能清楚的讓調(diào)用者知道參數(shù)的含義; - 參數(shù)標(biāo)簽可以用
_表示可以省略,代碼實現(xiàn)如下:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let a = sum2(10, 20)
print("\(a)")
}
func sum2(_ a:Int,_ b:Int) -> Int {
a + b
}
}
默認(rèn)參數(shù)值
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
check(name: "Jack", age: 30, job: "General")
check(age: 30)
}
func check(name: String = "liyanyan",age: Int,job :String = "none" ) -> Void {
print("name = \(name),age = \(age),job = \(job)")
}
}
- 打印結(jié)果如下:

Snip20210728_45.png
- 第二次調(diào)用時,只傳年齡參數(shù),其他兩個參數(shù)有默認(rèn)值,可以不用再傳參數(shù);
- 在函數(shù)調(diào)用時,默認(rèn)參數(shù)可以傳遞參數(shù),也可以不傳遞參數(shù);
可變參數(shù)
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let sum = sum3(10,20,30,40)
print("sum = \(sum)")
}
func sum3(_ numbers: Int...) -> Int {
var result = 0
for number in numbers{
result+=number
}
return result
}
}
-
numbers是一組整型參數(shù),可以傳遞多個整型參數(shù),即可變參數(shù); - 一個函數(shù)最多只有一個可變參數(shù);
- 緊跟在可變參數(shù)后面的參數(shù)不能省略參數(shù)標(biāo)簽;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
test(10,20,30, string: "li", "yanyan")
}
func test(_ numbers: Int..., string: String, _ other: String) -> Void {
}
}
輸入輸出參數(shù)inout
- 可以用
inout定義一個輸入輸出參數(shù):可以在函數(shù)內(nèi)部修改外部實參的值;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var value = 10
add(&value)
print(value)
}
func add(_ num: inout Int) -> Void {
num = 20
}
}
-
inout修飾符,可以在函數(shù)體內(nèi)部改變外界變量的值; - 可變參數(shù),不可以用
inout修飾符進行修飾; -
inout修飾符修飾的參數(shù)不能有默認(rèn)值; -
inout參數(shù)的本質(zhì)是地址傳遞; -
inout參數(shù)只能傳入可以被多次賦值的;
函數(shù)重載
- 函數(shù)名相同;
- 參數(shù)個數(shù)不同 / 參數(shù)類型不同 / 參數(shù)標(biāo)簽不同;
- 函數(shù)重載與函數(shù)的返回值類型無關(guān);
- 默認(rèn)參數(shù)值與函數(shù)重載一起使用時會產(chǎn)生二義性,但編譯器不會報錯;
- 可變參數(shù),省略參數(shù)標(biāo)簽與函數(shù)重載一起使用時會產(chǎn)生二義性,編譯器有可能會報錯;
內(nèi)聯(lián)函數(shù)
- Xcode如果開啟了編譯優(yōu)化(Release模式會默認(rèn)開啟優(yōu)化),編譯器會默認(rèn)將某些函數(shù)變成內(nèi)聯(lián)函數(shù),即將函數(shù)調(diào)用展開成函數(shù)體;

Snip20210728_46.png
- 函數(shù)體比較長,包含遞歸調(diào)用,包含動態(tài)派發(fā) 不會使用內(nèi)聯(lián)函數(shù);
函數(shù)類型
- 每一個函數(shù)都是有類型的,函數(shù)類型有形參類型和返回值類型組成;
函數(shù)類型作為函數(shù)參數(shù)
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
cal(add1, 10, 5)
}
func add1(a: Int,b: Int) -> Int {
a + b
}
func diff(a: Int,b: Int) -> Int {
a - b
}
func cal(_ math: (Int,Int) -> Int,_ m: Int,_ n: Int) -> Void {
print("reslut = \(math(m,n))")
}
}
-
(Int,Int) -> Int是函數(shù)類型,作為另一個函數(shù)的參數(shù);
函數(shù)類型作為函數(shù)的返回值
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let reslut = forward(true)(3)
print("result = \(reslut)")
}
func next(_ input: Int) -> Int {
input + 1
}
func previous(_ input: Int) -> Int {
input - 1
}
func forward(_ forward: Bool) -> (Int) -> Int{
forward ? next : previous
}
}
- 最后的打印結(jié)果為4,forward返回的是next函數(shù),然后傳入3,+1最后結(jié)果為4;
- 返回值是函數(shù)類型的函數(shù),我們稱之為高階函數(shù);
typealias
- 用來給類型起別名;
- typealias Long = Int64
嵌套函數(shù)
- 將函數(shù)定義在函數(shù)內(nèi)部;
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let reslut = forward(true)(3)
print("result = \(reslut)")
}
func forward(_ forward: Bool) -> (Int) -> Int{
func next(_ input: Int) -> Int {
input + 1
}
func previous(_ input: Int) -> Int {
input - 1
}
return forward ? next : previous
}
}
- 內(nèi)部函數(shù)只能在當(dāng)前函數(shù)內(nèi)部調(diào)用;
@inline
@inline(never) func test(){
print("test")
}
- 永遠不會被內(nèi)聯(lián),即使開啟了編譯器優(yōu)化
@inline(_always) func test(){
print("test")
}
- 開啟編譯器優(yōu)化后,即使代碼實現(xiàn)很長,也會被內(nèi)聯(lián)(遞歸與動態(tài)派發(fā)的函數(shù)除外);
- 在Release模式下,編譯器已經(jīng)開啟優(yōu)化,會自動決定哪些函數(shù)會被內(nèi)聯(lián),因此沒有必要使用@inline;