Swfit:函数专题

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)()) // 这里要加括号,如果不加单单只是一个函数,并没有调用

 

猜你喜欢

转载自blog.csdn.net/shijie97/article/details/83990101