微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift函数

函数是一组特定的代码块,执行特定的任务。当你需要执行一个函数体时,你只需要调用函数的标示名。

在Swift中,函数是足够强大和灵活的。你可以传递参数,并且在函数执行完毕时也可以返回数据。参数可以提供认值,以简化函数调用

一个函数都是一个类型,这意味着可以你可以将函数作为参数传递到其他函数内,并返回一个函数。也可以将其他函数封装到一个函数内形成嵌套函数

定义和调用函数

下面代码定义了一个sayHello的函数,这个函数接受一个String类型的参数,并返回一个String类型的数据。当你想调用这个函数时,只需调用函数名,并传递想要传递的数据。

func sayHello(personName: String) -> String {
    let greeting = "Hello," + personName + "!"
    return greeting
}

print(sayHello("阳君"))
// prints "Hello,阳君!"

函数的参数和返回值

在Swift中,函数的参数和返回值是非常灵活的,你可以定义任何类型的参数和返回值。

函数不携带参数

// 无参数,只有一个String类型的返回值
func sayHelloWorld() -> String {
    return "hello,world"
}

print(sayHelloWorld())
// prints "hello,world"

函数携带多个参数

// 传入两个参数,并返回一个String类型的数据
func sayHello(personName: String,alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return "Hello again,\(personName)!"
    } else {
        return "Hello,\(personName)!"
    }
}

print(sayHello("阳君",alreadyGreeted: true))
// prints "Hello again,阳君!"

函数没有返回值

// 传入一个String类型的数据,不返回任何数据
func sayGoodbye(personName: String) {
    print("Goodbye,\(personName)!")
}

sayGoodbye("阳君") // prints "Goodbye,阳君!"

函数有返回值

函数一个返回值

// 返回一个Int类型的数据
func printAndCount(stringToPrint: String) -> Int {
    print(stringToPrint)
    return stringToPrint.characters.count
}

printAndCount("hello,world") // prints "hello,world"

函数有多个返回值

// 返回元组数据
func minMax(array: [Int]) -> (min: Int,max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin,currentMax)
}

let bounds = minMax([8,-6,2,109,3,71])
print("min is \(bounds.min) and max is \(bounds.max)")
// prints "min is -6 and max is 109"

返回类型可选

函数执行完毕时,会返回一定的数据。在有的情况下函数会返回nil的数据,此时只需要在声明的函数返回类型后添加“?”。

// 返回一个元组或Nil
func minMax(array: [Int]) -> (min: Int,max: Int)? {
    if array.isEmpty {
        return nil
    }
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin,currentMax)
}

if let bounds = minMax([8,71]) {
    print("min is \(bounds.min) and max is \(bounds.max)")
    // prints "min is -6 and max is 109"
}

参数名

指定外部参数名

在外部调用函数时,我们希望在传递参数的数据前有提示,这样提升了代码的阅读性。如sayHello("Bill","Ted") 增加外部参数名后变为sayHello(to: "Bill",and: "Ted")

// 指定外部参数名to和and
func sayHello(to person: String,and anotherPerson: String) -> String {
    return "Hello \(person) and \(anotherPerson)!"
}

print(sayHello(to: "Bill",and: "Ted"))
// prints "Hello Bill and Ted!"

省略外部参数名

在一些特有的情况下,我们并不需要外部参数名。由于swift的函数机制,除第一个外的其他参数必须携带外部参数名。如果你不想使用外部参数名,在声明的时候可使用_ 代替参数名。

// 使用_省略外面参数名,
func someFunction(firstParameterName: Int,_ secondParameterName: Int) {

}

someFunction(1,2)

参数认值

函数内部,我们可以为参数设置认值。如果外部不传递数据时,我们就使用设置的认值。

// 设置认值,当用户不传入时,使用认值
func someFunction(parameterWithDefault: Int = 12) {
    print("\(parameterWithDefault)")
}

someFunction(6) // 6
someFunction() // 12

可变参数

有的时候,我们只知道传入函数的数据类型,不知道传入函数的数据个数,这个时候我们可以使用...代表允许传入未知个数的数据。

// 传入的参数类型已知Double,个数未知
func arithmeticmean(numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}

print("\(arithmeticmean(1,2,3,4,5))") // 3.0
print("\(arithmeticmean(3,8.25,18.75))") // 10.0

常量和变量参数

函数中,参数认是let不可变。如果我们想让这个数据可变,可能需要在函数内用一个var转化。Swift鉴于这种情况,对参数做了优化,我们只需要用var声明这个参数,在函数内就可改变它的数据。

// 认为let常量参数,也可声明var可变参数,在函数内直接修改
func alignRight(var string: String,totalLength: Int,pad: Character) -> String {
    let amountToPad = totalLength - string.characters.count
    if amountToPad < 1 {
        return string
    }
    let padString = String(pad)
    for _ in 1...amountToPad {
        string = padString + string
    }
    return string
}

let originalString = "hello"
let paddedString = alignRight(originalString,totalLength: 10,pad: "-")
print("originalString:\(originalString); paddedString:\(paddedString);")
// originalString:hello; paddedString:-----hello;

In-Out参数

当我们使用var让参数可变的时候,往往会思考我们改变这个参数的数据,是否会改变外部的数据呢?当你改变var声明的数据时,外面数据是不会发生任何改变的。但是有的情况,我们又希望外部数据也会跟着变化,此时我们只需要使用inout声明这个参数。

// 使用inout声明的参数,在函数修改参数值时,外面参数值也会变
func swapTwoInts(inout a: Int,inout _ b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt,&anotherInt)
print("someInt is Now \(someInt),and anotherInt is Now \(anotherInt)")
// prints "someInt is Now 107,and anotherInt is Now 3"

函数类型

所有的函数都是一个类型,只是这个类型有点特殊,它携带参数和返回值。也就意味着,你可以将一个函数一个let或var声明的属性代替。当我们调用这个函数时,只需要调用这个声明的属性

使用函数类型

// 加法
func addTwoInts(a: Int,_ b: Int) -> Int {
    return a + b
}

// 乘法
func multiplyTwoInts(a: Int,_ b: Int) -> Int {
    return a * b
}

// 函数体赋值为参数
var mathFunction: (Int,Int) -> Int = addTwoInts
print("Result: \(mathFunction(2,3))") // prints "Result: 5"

// 函数体指向替换
mathFunction = multiplyTwoInts
print("Result: \(mathFunction(2,3))") // prints "Result: 6"

// 函数体传递
let anotherMathFunction = addTwoInts //
// anotherMathFunction is inferred to be of type (Int,Int) -> Int
print("\(anotherMathFunction)")

函数做参数

下面的例子介绍了怎么将一个函数作为一个参数传递到另一个函数

// 加法
func addTwoInts(a: Int,_ b: Int) -> Int {
    return a + b
}

// 其中一个参数为一个函数体
func printMathResult(mathFunction: (Int,Int) -> Int,_ a: Int,_ b: Int) { print("Result: \(mathFunction(a,b))") } printMathResult(addTwoInts,5) // prints "Result: 8"

函数做返回值

函数作为函数的参数传递,也就意味着函数可以作为函数的返回值。

//1
func stepForward(input: Int) -> Int {
    return input + 1
}

//1
func stepBackward(input: Int) -> Int {
    return input - 1
}

// 使用函数体做返回类型
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}

var currentValue = 3
// 此时moveNearerToZero指向stepForward函数
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// 调用函数体
currentValue = moveNearerToZero(currentValue)
print("\(currentValue)... ") // prints “2...”

嵌套函数

本章介绍的函数体都是全局函数的例子,它被定义在全局作用域中。您也可以在一个函数体内再定义一个函数,称为嵌套函数

嵌套函数认情况下是隐藏的,但你仍然可以调用和使用嵌套函数外的数据。

// 函数体内部嵌套函数,并做返回类型
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    // 嵌套函数1
    func stepForward(input: Int) -> Int {
        return input + 1
    }

    // 嵌套函数2
    func stepBackward(input: Int) -> Int {
        return input - 1
    }

    return backwards ? stepBackward : stepForward
}

var currentValue = -2
let moveNearerToZero = chooseStepFunction(currentValue > 0)
currentValue = moveNearerToZero(currentValue)
print("\(currentValue)... ") // prints "-1..."

其他

参考资料

The Swift Programming Language (Swift 2.1)

文档修改记录

时间 描述
2015-10-27 根据 The Swift Programming Language (Swift 2.1)总结

版权所有:http://blog.csdn.net/y550918116j

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐