1. 返回为空的写法
import UIKit
func printHello() -> () { // 返回为空,可以省略,也可以用()或Void
print("Hello")
}
func printHello() { // 返回为空,可以省略,也可以用()或Void
print("Hello")
}
func printHello() -> Void { // 返回为空,可以省略,也可以用()或Void
print("Hello")
}
2. 带有默认参数的写法,建议让默认参数的放在最后
import UIKit
func printHello(name: String, greeting: String = "Hello", punctuation: String = "!") -> String { // 参数可以有默认值,建议将含有默认参数值的参数放在最后
return greeting + " " + name + punctuation
}
printHello(name: "Zhoushijie") // 可以默认
printHello(name: "Zhoushijie", greeting: "Hey", punctuation: "?") // 也可以全部指定
3. 可变参数
import UIKit
func getAve(nums: Double ...) -> Double {
var sum: Double = 0
for item in nums {
sum += item
}
return sum / Double(nums.count)
}
getAve(nums: 1, 2, 3) // 这里就返回平均值
4. 内部参数名和外部参数名,以及省略外部参数名
import UIKit
func Add(first num1: Int, num2: Int) -> Int { // 第一个参数指定外部参数名,第二个的num2既是内又是外
return num1 + num2 // 函数体内部只能用内部参数名
}
Add(first: 1, num2: 2) // 调用函数的时候只能用外部参数名
func Add2(num1: Int, num2: Int) -> Int {
return num1 + num2
}
Add2(num1: 1, num2: 2) // 调用的时候内部参数名必须指定不然报错
// 省略外部参数名,可以在调用的时候不用指定外部参数名
func Add3(_ num1: Int, _ num2: Int) -> Int {
return num1 + num2
}
Add3(1, 2)
4. inout关键字
import UIKit
func DivToHalf(number: Int) ->Double {
number /= 2.0
return Double(number)
}
// 等价于这里多加了一个let,相当于常量
func DivToHalf2(let number: Int) ->Double {
number /= 2.0 // 报错,因为常量不能改变
return Double(number)
}
// 引入inout,相当于传引用,在函数体里面也会变,结束调用仍然会变
func DivToHalf2(number: inout Double) ->Double {
number /= 2
return number
}
5. 数组与inout
import UIKit
// 数组是结构体类型,因此传进去的是值而不是引用,因此也要遵循inout
func initArr(arr: inout [Int], by value: Int) {
for i in 0 ..< arr.count {
arr[i] = value // 如果不加inout这里会报错,因为默认arr是常量
}
}
var arr = [1, 2, 3, 4, 5]
initArr(arr: &arr, by: 0)
6. 函数作为参数值、函数式编程初体验(map、filter、reduce)
import UIKit
// 传入一个数组和一个函数,对数组中的每个元素应用函数中的方法进行改变
func changeScores(scores: inout [Int], by changeScore: (Int) -> Int) {
for (index, score) in scores.enumerated() {
scores[index] = changeScore(score) // 这里改变了数组的值,所以要用inout来传引用
}
}
func changeScore1(score: Int) -> Int {
return score * 2
}
func changeScore2(score: Int) -> Int {
return score * 3
}
var arr = [1, 2, 3, 4, 5]
changeScores(scores: &arr, by: changeScore1)
changeScores(scores: &arr, by: changeScore2)
// map 不改变arr的值
arr.map(changeScore1) // map函数对数组里面每一个元素进行括号里的操作
arr
// filter 不改变arr的值
func fail(score: Int) -> Bool { // 需要返回一个布尔值
return score < 10
}
arr.filter(fail)
arr
// reduce 不改变arr的值
// func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Int) throws -> Result) rethrows -> Result
// reduce函数中的第一个参数的类型必须和返回值相同,因为要不断迭代进行,因此你看类型都是Result类型的
func add(a: Int, b: Int) -> Int {
return a + b
}
arr.reduce(0, add)
arr.reduce(0, +) // 同上
arr
func concatenate(str: String, num: Int) -> String {
return str + String(num) + " "
}
arr.reduce("", concatenate)
6. 函数作为返回值
import UIKit
func output(score: Int) -> () -> String {
// 将下面两个函数作为内部函数,这样可以避免向外暴露接口
func printGood() -> String {
return "Good!"
}
func printWonderful() -> String {
return "Wonderful!"
}
return score >= 60 ? printWonderful : printGood
}
let myScore = 100
print(output(score: myScore)()) // 这里要加括号,如果不加单单只是一个函数,并没有调用