函数

作者: VNSKing | 来源:发表于2015-05-25 15:37 被阅读11次

    外部参数(External Parameter Names)

    有时候,调用函数时,给每个参数命名是非常有用的,因为这些参数名可以指出各个实参的用途是什么。

    如果你希望函数的使用者在调用函数时提供参数名字,那就需要给每个参数除了局部参数名外再定义一个外部参数名。外部参数名写在局部参数名之前,用空格分隔。

    <pre><code>func someFunction(externalParameterName localParameterName: Int) {
    // function body goes here, and can use localParameterName
    // to refer to the argument value for that parameter
    }</pre></code>

    注意: 如果你提供了外部参数名,那么函数在被调用时,必须使用外部参数名。

    简写外部参数名(Shorthand External Parameter Names)

    如果你需要提供外部参数名,但是局部参数名已经定义好了,那么你不需要写两次参数名。相反,只写一次参数名,并用井号(#)作为前缀就可以了。这告诉 Swift 使用这个参数名作为局部和外部参数名。

    下面这个例子定义了一个叫 containsCharacter 的函数,使用井号(#)的方式定义了外部参数名:
    <pre><code>func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
    for character in string {
    if character == characterToFind {
    return true
    }
    }
    return false
    }</pre></code>

    这样定义参数名,使得函数体更为可读,清晰,同时也可以以一个不含糊的方式被调用:

    <pre><code>
    let containsAVee = containsCharacter(string: "aardvark", characterToFind: "v")
    // containsAVee equals true, because "aardvark" contains a "v”
    </pre></code>

    默认参数值(Default Parameter Values)

    你可以在函数体中为每个参数定义默认值。当默认值被定义后,调用这个函数时可以忽略这个参数。

    注意: 将带有默认值的参数放在函数参数列表的最后。这样可以保证在函数调用时,非默认参数的顺序是一致的,同时使得相同的函数在不同情况下调用时显得更为清晰。

    join函数,其中joiner有了默认参数值:
    <pre><code>
    func join(string s1: String, toString s2: String, withJoiner joiner: String = " ") -> String {
    return s1 + joiner + s2
    }</pre></code>

    注意:当你未给带默认值的参数提供外部参数名时,Swift 会自动提供外部名字。此时外部参数名与局部名字是一样的,就像你已经在局部参数名前写了井号(#)一样。

    可变参数(Variadic Parameters)

    一个可变参数(variadic parameter)可以接受一个或多个值。函数调用时,你可以用可变参数来传入不确定数量的输入参数。通过在变量类型名后面加入(...)的方式来定义可变参数。

    传入可变参数的值在函数体内当做这个类型的一个数组。例如,一个叫做 numbers 的 Double... 型可变参数,在函数体内可以当做一个叫 numbers 的 Double[] 型的数组常量。

    下面的这个函数用来计算一组任意长度数字的算术平均数:
    <pre><code>func arithmeticMean(numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
    total += number
    }
    return total / Double(numbers.count)
    }
    arithmeticMean(1, 2, 3, 4, 5)
    // returns 3.0, which is the arithmetic mean of these five numbers
    arithmeticMean(3, 8, 19)
    // returns 10.0, which is the arithmetic mean of these three numbers
    </pre></code>

    注意: 一个函数至多能有一个可变参数,而且它必须是参数表中最后的一个。这样做是为了避免函数调用时出现歧义。

    如果函数有一个或多个带默认值的参数,而且还有一个可变参数,那么把可变参数放在参数表的最后。

    变量参数(Variable Parameters)

    函数参数默认是常量。试图在函数体中更改参数值将会导致编译错误。这意味着你不能错误地更改参数值。

    但是,有时候,如果函数中有传入参数的变量值副本将是很有用的。你可以通过指定一个或多个参数为变量参数,从而避免自己在函数中定义新的变量。变量参数不是常量,你可以在函数中把它当做新的可修改副本来使用。

    通过在参数名前加关键字 var 来定义变量参数:
    <pre><code>
    func alignRight(var string: String, totalLength: Int, pad: Character) -> String {
    let amountToPad = totalLength - count(string)
    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, 10, "-")
    // paddedString is equal to "-----hello"
    // originalString is still equal to "hello"</pre></code>

    注意: 对变量参数所进行的修改在函数调用结束后便消失了,并且对于函数体外是不可见的。变量参数仅仅存在于函数调用的生命周期中。

    输入输出参数(In-Out Parameters)

    变量参数,正如上面所述,仅仅能在函数体内被更改。如果你想要一个函数可以修改参数的值,并且想要在这些修改在函数调用结束后仍然存在,那么就应该把这个参数定义为输入输出参数(In-Out Parameters)。

    定义一个输入输出参数时,在参数定义前加 inout 关键字。一个输入输出参数有传入函数的值,这个值被函数修改,然后被传出函数,替换原来的值。

    你只能将变量作为输入输出参数。你不能传入常量或者字面量(literal value),因为这些量是不能被修改的。当传入的参数作为输入输出参数时,需要在参数前加&符,表示这个值可以被函数修改。

    注意: 输入输出参数不能有默认值,而且可变参数不能用 inout 标记。如果你用 inout 标记一个参数,这个参数不能被 var 或者 let 标记。

    下面是例子,swapTwoInts 函数,有两个分别叫做 a 和 b 的输入输出参数:
    <pre><code>
    func swapTwoInts(inout a: Int, inout b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
    }</pre></code>

    这个 swapTwoInts 函数仅仅交换 a 与 b 的值。该函数先将 a 的值存到一个暂时常量 temporaryA 中,然后将 b 的值赋给 a,最后将 temporaryA 幅值给 b。

    你可以用两个 Int 型的变量来调用 swapTwoInts。需要注意的是,someInt 和 anotherInt 在传入 swapTwoInts 函数前,都加了 & 的前缀:

    <pre><code>
    var someInt = 3
    var anotherInt = 107
    swapTwoInts(&someInt, &anotherInt)
    println("someInt is now (someInt), and anotherInt is now (anotherInt)")
    // prints "someInt is now 107, and anotherInt is now 3”</pre></code>

    从上面这个例子中,我们可以看到 someInt 和 anotherInt 的原始值在 swapTwoInts 函数中被修改,尽管它们的定义在函数体外。

    注意: 输入输出参数和返回值是不一样的。上面的 swapTwoInts 函数并没有定义任何返回值,但仍然修改了 someInt 和 anotherInt 的值。输入输出参数是函数对函数体外产生影响的另一种方式。

    相关文章

      网友评论

          本文标题:函数

          本文链接:https://www.haomeiwen.com/subject/qirrqttx.html