- 函數(shù)相當(dāng)于OC中的方法
- 函數(shù)的格式如下
func 函數(shù)名(參數(shù)列表) -> 返回值類型 {
代碼塊
return 返回值
}
- func是關(guān)鍵字,多個(gè)參數(shù)列表之間可以用逗號(,)分隔,也可以沒有參數(shù)
- 使用箭頭“->”指向返回值類型
- 如果函數(shù)沒有返回值,返回值為Void.并且“->返回值類型”部分可以省略
常見的函數(shù)類型
// 1.沒有參數(shù),沒用返回值
func about() -> Void {
print("iphone6s plus")
}
// 調(diào)用函數(shù)
about()
// 簡單寫法
// 如果沒用返回值,Void可以寫成()
func about1() -> () {
print("iphone6s plus")
}
// 如果沒有返回值,后面的內(nèi)容可以都不寫
func about2() {
print("iphone6s plus")
}
about2()
// 2.有參數(shù),沒用返回值
func callPhone(phoneNum : String) {
print("打電話給\(phoneNum)")
}
callPhone("+86 110")
// 3.沒用參數(shù),有返回值
func readMessage() -> String {
return "吃飯了嗎?"
}
var str = readMessage()
print(str)
// 4.有參數(shù),有返回值
func sum(num1 : Int, num2 : Int) -> Int {
return num1 + num2
}
var result = sum(20, num2: 30)
print(result)
// 5.有多個(gè)返回值的函數(shù)
let nums = [1, 3, 4, 8, 22, 23]
func getNumCount(nums : [Int]) -> (oddCount : Int, evenCount : Int) {
var oddCount = 0
var evenCount = 0
for num in nums {
if num % 2 == 0 {
oddCount++
} else {
evenCount++
}
}
return (oddCount, evenCount)
}
let result = getNumCount(nums)
result.oddCount
result.evenCount
函數(shù)的使用注意
- 注意一: 外部參數(shù)和內(nèi)部參數(shù)
- 在函數(shù)內(nèi)部可以看到的參數(shù),就是內(nèi)部參數(shù)
- Swift2.0以前, 默認(rèn)情況下的參數(shù)都是內(nèi)部參數(shù)
- Swift2.0開始, 默認(rèn)將第二個(gè)參數(shù)名稱作為外部參數(shù)
- 在函數(shù)外面可以看到的參數(shù),就是外部參數(shù)
- 默認(rèn)情況下,從第二個(gè)參數(shù)開始,參數(shù)名稱既是內(nèi)部參數(shù)也是外部參數(shù)
- 如果第一個(gè)參數(shù)也想要有外部參數(shù),可以設(shè)置標(biāo)簽:在變量名前加標(biāo)簽即可
- 如果不想要外部參數(shù),可以在參數(shù)名稱前加_
// Swift2.0之前, 默認(rèn)是不會將第二個(gè)參數(shù)開始的參數(shù)名稱作為外部參數(shù)的, 必須自己手動(dòng)指定
- 在函數(shù)內(nèi)部可以看到的參數(shù),就是內(nèi)部參數(shù)
// num1和a是外部參數(shù)的名稱
func ride(num1 num1 : Int, a num2 : Int, b num3 : Int) -> Int {
return num1 * num2 * num3
}
var result1 = ride(num1: 20, a: 4, b: 5)
// 方法的重載:方法名稱相同,但是參數(shù)不同,可以稱之為方法的重載(了解)
func ride(num1: Int, _ num2 :Int) -> Int {
return num1 * num2
}
var result2 = ride(20, 20)
- 注意二: 默認(rèn)參數(shù)
- 某些情況,如果沒有傳入具體的參數(shù),可以使用默認(rèn)參數(shù)
- 當(dāng)默認(rèn)值被定義后实抡,調(diào)用這個(gè)函數(shù)時(shí)可以忽略這個(gè)參數(shù)
- 其它語言的默認(rèn)參數(shù)必須寫在最后面, Swift可以寫在任意位置
- 建議將帶有默認(rèn)值的參數(shù)放在函數(shù)參數(shù)列表的最后姐帚。這樣可以保證在函數(shù)調(diào)用時(shí)恩沛,非默認(rèn)參數(shù)的順序是一致的,同時(shí)使得相同的函數(shù)在不同情況下調(diào)用時(shí)顯得更為清晰胚股。
// 卡布奇諾是默認(rèn)參數(shù)
func makecoffee(type :String = "卡布奇諾") -> String {
return "制作一杯\(type)咖啡。"
}
let coffee1 = makecoffee("拿鐵") // coffee1 = 拿鐵
let coffee2 = makecoffee() // coffee2 = 卡布奇諾
- 注意三: 可變參數(shù)
- swift中函數(shù)的參數(shù)個(gè)數(shù)可以變化裙秋,它可以接受不確定數(shù)量的輸入類型參數(shù)
- 它們必須具有相同的類型
- 我們可以通過在參數(shù)類型名后面加入(...)的方式來指示這是可變參數(shù)
func sum(numbers:Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total
}
sum(100.0, 20, 30)
sum(30, 80)
- 注意四: 引用類型(指針的傳遞)
- 默認(rèn)情況下,函數(shù)的參數(shù)是值傳遞.如果想改變外面的變量,則需要傳遞變量的地址
- 必須是變量,因?yàn)樾枰趦?nèi)部改變其值
- Swift提供的inout關(guān)鍵字就可以實(shí)現(xiàn)
- 對比下列兩個(gè)函數(shù)
// 函數(shù)一:值傳遞
func swap(var a : Int, var b : Int) {
let temp = a;
a = b;
b = temp
print("a:\(a), b:\(b)")
}
var a = 10
var b = 20
swap(a, b: b)
print("a:\(a), b:\(b)")
// 函數(shù)二:指針的傳遞
func swap1(inout a : Int, inout b : Int) {
let temp = a
a = b
b = temp
print("a:\(a), b:\(b)")
}
swap1(&a, b: &b)
print("a:\(a), b:\(b)")
- 函數(shù)的嵌套使用
- swift中函數(shù)可以嵌套使用
- 即函數(shù)中包含函數(shù),但是不推薦該寫法
// 函數(shù)的嵌套
let value = 55
func test() {
func demo() {
print("demo \(value)")
}
print("test")
demo()
}
demo() // 錯(cuò)誤
test() // 執(zhí)行函數(shù)會先打印'test',再打印'demo'
函數(shù)的類型
- 函數(shù)類型的概念
- 每個(gè)函數(shù)都有屬于自己的類型琅拌,由函數(shù)的參數(shù)類型和返回類型組成
- 這個(gè)例子中定義了兩個(gè)簡單的數(shù)學(xué)函數(shù):addTwoInts 和 multiplyTwoInts
- 這兩個(gè)函數(shù)都傳入兩個(gè) Int 類型, 返回一個(gè)合適的Int值
- 這兩個(gè)函數(shù)的類型是 (Int, Int) -> Int
- 每個(gè)函數(shù)都有屬于自己的類型琅拌,由函數(shù)的參數(shù)類型和返回類型組成
// 定義兩個(gè)函數(shù)
func addTwoInts(a : Int, b : Int) -> Int {
return a + b
}
func multiplyTwoInt(a : Int, b : Int) -> Int {
return a * b
}
- 抽取兩個(gè)函數(shù)的類型,并且使用
// 定義函數(shù)的類型
var mathFunction : (Int, Int) -> Int = addTwoInts
// 使用函數(shù)的名稱
mathFunction(10, 20)
// 給函數(shù)的標(biāo)識符賦值其他值
mathFunction = multiplyTwoInt
// 使用函數(shù)的名稱
mathFunction(10, 20)
- 函數(shù)作為方法的參數(shù)
// 將函數(shù)的類型作為方法的參數(shù)
func printResult(a : Int, b : Int, calculateMethod : (Int, Int) -> Int) {
print(calculateMethod(a, b))
}
printResult(10, b: 20, calculateMethod: addTwoInts)
printResult(10, b: 20, calculateMethod: multiplyTwoInt)
- 函數(shù)作為方法的返回值
// 1.定義兩個(gè)函數(shù)
func stepForward(num : Int) -> Int {
return num + 1
}
func stepBackward(num : Int) -> Int {
return num - 1
}
// 2.定義一個(gè)變量,希望該變量經(jīng)過計(jì)算得到0
var num = -4
// 3.定義獲取哪一個(gè)函數(shù)
func getOprationMethod(num : Int) -> (Int) -> Int {
return num <= 0 ? stepForward : stepBackward
}
// 4.for循環(huán)進(jìn)行操作
while num != 0 {
let oprationMethod = getOprationMethod(num)
num = oprationMethod(num)
print(num)
}
常量參數(shù)和變量參數(shù)(Constant and Variable Parameters)
- 函數(shù)參數(shù)默認(rèn)是常量, 在函數(shù)內(nèi)部不能修改
- 如果想在函數(shù)中修改參數(shù), 必須在參數(shù)前加上var
- 注意
- 對變量參數(shù)所進(jìn)行的修改在函數(shù)調(diào)用結(jié)束后便消失了摘刑,并且對于函數(shù)體外是不可見的进宝。變量參數(shù)僅僅存在于函數(shù)調(diào)用的生命周期中
func sum4(let i: Int, let j: Int) {
print(i + j)
}
sum4(10, j: 20)
var num1 = 10
var num2 = 20
//func swap(value1: Int, value2: Int){
// let temp = value1
// value1 = value2
// value2 = temp
//}
// 注意: 操作的是局部變量, 對實(shí)參沒有影響
func swap1(var value1: Int, var value2: Int){
print("交互前: value1 = \(value1), value2 = \(value2)")
let temp = value1
value1 = value2
value2 = temp
print("交互后: value1 = \(value1), value2 = \(value2)")
}
swap1(num1, value2: num2)
print(num1)
print(num2)
輸入輸出參數(shù)(In-Out Parameters)
變量參數(shù),正如上面所述枷恕,僅僅能在函數(shù)體內(nèi)被更改党晋。如果你想要一個(gè)函數(shù)可以修改參數(shù)的值,并且想要在這些修改在函數(shù)調(diào)用結(jié)束后仍然存在徐块,那么就應(yīng)該把這個(gè)參數(shù)定義為輸入輸出參數(shù)(In-Out Parameters)
定義一個(gè)輸入輸出參數(shù)時(shí)未玻,在參數(shù)定義前加 inout 關(guān)鍵字
-
注意
- 輸入輸出參數(shù)不能有默認(rèn)值,而且可變參數(shù)不能用 inout 標(biāo)記胡控。如果你用 inout 標(biāo)記一個(gè)參數(shù)扳剿,這個(gè)參數(shù)不能被 var 或者 let 標(biāo)記。
func swap2(inout value1: Int, inout value2: Int){
print("交互前: value1 = \(value1), value2 = \(value2)")
let temp = value1
value1 = value2
value2 = temp
print("交互后: value1 = \(value1), value2 = \(value2)")
}
swap2(&num1, value2: &num2)
print(num1)
print(num2)
可變參數(shù)(Variadic Parameters)
- 一個(gè)可變參數(shù)可以接收零個(gè)或多個(gè)值
- 如果沒有變參函數(shù) , 并且函數(shù)的參數(shù)個(gè)數(shù)又不確定那么只能寫多個(gè)方法或者用將函數(shù)參數(shù)改為集合
- 格式 func method(parameter: Int...){}
- 可變參數(shù)在函數(shù)中可以當(dāng)做一個(gè)數(shù)組
注意
- 一個(gè)函數(shù)最多只能有一個(gè)可變參數(shù)
- 變參只能是同種類型的數(shù)據(jù)
- 變參必須指定數(shù)據(jù)類型
- 如果函數(shù)有一個(gè)或多個(gè)帶默認(rèn)值的參數(shù)昼激,而且還有一個(gè)可變參數(shù)舞终,那么把可變參數(shù)放在參數(shù)表的最后
func sum5(numbers: Int...) {
// print(numbers)
var sum = 0
for number in numbers {
sum += number
}
print(sum)
}
sum5(1, 2, 3)
// 不推薦寫法, 和默認(rèn)值一樣, 變參最好寫在最后
func sum6(numbers: Int..., var sum: Int) {
// print(numbers)
for number in numbers {
sum += number
}
print(sum)
}
sum6(1, 2, 3, sum: 0)
// 推薦寫法
func sum7(var sum: Int = 100, numbers: Int...) {
// print(numbers)
for number in numbers {
sum += number
}
print(sum)
}
sum7(numbers: 1, 2, 3)
// 一個(gè)函數(shù)中只能有一個(gè)變參
//func sum8(numbers: Int..., values: Int...){
// print(numbers)
// print(values)
//}
// 有參數(shù)有返回值
func sum8(i: Int, j: Int) -> Int {
return i + j
}
let result = sum8(10, j: 20)
print(result)