一珊拼、函數(shù)的定義
注意??:函數(shù)參數(shù)默認情況下是 let 參數(shù)的值是不能更改的
函數(shù)的形式
func 函數(shù)名稱(參數(shù))->(返回值類型){
return 返回值
}
其中函數(shù)參數(shù)可有可無盾计,參數(shù)的個數(shù)可以有一個也可以有多個
函數(shù)的返回值 可有可無 如下例子
1搞糕、無參數(shù)钙皮、無返回值
//MARK: -- 沒有返回參數(shù)的函數(shù)
func sayHello(){
print("Hellow")
}
2蜂科、有參數(shù) 無返回值
func sayHelloToSomeone(_ name:String){
print("Hellow \(name)")
}
3、無參數(shù) 有返回值
func p() -> CGFloat{
return 3.14
}
4短条、有參數(shù) 有返回值
func sum(_ v1:Int,_ v2:Int) -> Int{
return v1 + v2
}
二导匣、隱式返回
如果整個函數(shù)體是一個單一表達式,那么函數(shù)會隱式返回這個表達式(也就是說可以把關(guān)鍵字 return 省掉 )
例如
func sum(_ v1:Int,_ v2:Int) -> Int{
v1 + v2
}
三茸时、返回元組:實現(xiàn)多個返回值
例
func calculate(v1: Int, v2: Int) -> (sum: Int, difference: Int, average: Int) {
let sum = v1 + v2
return (sum, v1 - v2, sum >> 1)
}
四贡定、函數(shù)中的參數(shù)標簽
函數(shù)中 參數(shù)明可以帶標簽
例如
func sum(unmber1 v1:Int,unmber1 v2:Int) -> Int{
return v1 + v2
}
調(diào)用方式
sum(unmber1: 10, unmber1: 20)
這里的 unmber1 和 unmber1 就是參數(shù)的標簽
再比如
func goToWork(at time: String) {
print("this time is \(time)")
}
調(diào)用方式
goToWork(at: "08:00")
這里的at 就是參數(shù)的標簽
標簽的作用就是提示 標簽可以使用 _ 來代替
如
func sum(_ v1:Int,_ v2:Int) -> Int{
return v1 + v2
}
五、函數(shù)中的默認參數(shù)
函數(shù)中默認參數(shù)指的是賦了初始值的參數(shù)可都,在調(diào)用函數(shù)的時候 默認參數(shù)可傳也可不傳
func check(name: String = "nobody", age: Int, job: String = "none") {
print("name=\(name), age=\(age), job=\(job)")
}
check(name: "Jack", age: 20, job: "Doctor") // name=Jack, age=20, job=Doctor
check(name: "Rose", age: 18) // name=Rose, age=18, job=none
check(age: 10, job: "Batman") // name=nobody, age=10, job=Batman
check(age: 15) // name=nobody, age=15, job=none
如上述函數(shù)中 name 缓待、job 都有默認值 age 沒有默認值 所以在調(diào)用函數(shù)的時候 除了age不能為空 其他均可不傳
注意??:函數(shù)中有默認參數(shù)時 一定要注意 必填參數(shù)有時不能省略標簽
比如
func test(_ first: Int = 10, middle: Int, _ last: Int = 30) { }
test(middle: 20)
如果上面函數(shù)的 middle參數(shù)的標簽省略 在調(diào)用 test函數(shù)的時候就不知道你傳的參數(shù)是哪個 所以會報錯
如下圖
六、函數(shù)中的可變參數(shù)
也就是說函數(shù)的參數(shù)不固定 可以為一個 也可以為多個
例如
func sum(_ numbers: Int...) -> Int {
var total = 0
for number in numbers {
total += number
}
return total
}
sum(10, 20, 30, 40)
注意??:
1渠牲、一個函數(shù)最多只能有一個可變參數(shù)
2旋炒、緊跟在可變參數(shù)后面的參數(shù) 不能省略標簽
如
func test(_ numbers: Int..., string: String, _ other: String) { }
test(10, 20, 30, string: "Jack", "Rose")
test函數(shù)的 string 參數(shù)不能省略標簽
原因是:如果緊跟在可變參數(shù)后面的參數(shù)省略了標簽 可變參數(shù)不知道從哪里結(jié)束 然后就把 后面的參數(shù)來當成是可變參數(shù) 所有就會報錯
七、函數(shù)中的輸入輸出函數(shù)(inout)
可以用inout定義一個輸入輸出參數(shù):
作用:可以在函數(shù)內(nèi)部修改外部實參
例如
func swapValues(_ v1: inout Int, _ v2: inout Int) {
let tmp = v1
v1 = v2
v2 = tmp
}
var num1 = 10
var num2 = 20
swapValues(&num1, &num2)
可變參數(shù)不能標記為inout
inout參數(shù)不能有默認值
inout參數(shù)只能傳入可以被多次賦值的
inout參數(shù)的本質(zhì)是地址傳遞(引用傳遞 也就是將參數(shù)的地址傳遞過去 然后根據(jù)地址去修改地址存的值)
八签杈、函數(shù)重載
規(guī)則
1瘫镇、函數(shù)名相同
2、參數(shù)個數(shù)不同 || 參數(shù)類型不同 || 參數(shù)標簽不同
func sum(v1: Int, v2: Int) -> Int {
v1 + v2
}
// 參數(shù)個數(shù)不同
func sum(v1: Int, v2: Int, v3: Int) -> Int {
v1 + v2 + v3
}
// 參數(shù)類型不同
func sum(v1: Int, v2: Double) -> Double {
Double(v1) + v2
}
// 參數(shù)類型不同
func sum(v1: Double, v2: Int) -> Double {
v1 + Double(v2)
}
// 參數(shù)標簽不同
func sum(_ v1: Int, _ v2: Int) -> Int {
v1 + v2
}
// 參數(shù)標簽不同
func sum(a: Int, b: Int) -> Int {
a + b
}
注意??:
返回值類型與函數(shù)重載無關(guān)
默認參數(shù)值和函數(shù)重載一起使用產(chǎn)生二義性時答姥,編譯器并不會報錯(在C++中會報錯)
可變參數(shù)铣除、省略參數(shù)標簽、函數(shù)重載一起使用產(chǎn)生二義性時鹦付,編譯器有可能會報錯
九尚粘、內(nèi)聯(lián)函數(shù)
使用@inline(never) 修飾函數(shù) 這個函數(shù)永遠不會被內(nèi)聯(lián)(即使開啟了編譯器優(yōu)化)
@inline(never) func test() {
print("test")
}
使用@inline(__always) 修飾函數(shù) 開啟編譯器優(yōu)化后,即使代碼很長敲长,也會被內(nèi)聯(lián)(遞歸調(diào)用函數(shù)背苦、動態(tài)派發(fā)的函數(shù)除外)
@inline(__always) func test() {
print("test")
}
在Release模式下互捌,編譯器已經(jīng)開啟優(yōu)化,會自動決定哪些函數(shù)需要內(nèi)聯(lián)行剂,因此沒必要使用@inline