五、函数 Functions

1. 函数

1.1 多返回值函数——使用元祖类型(tuple)作为函数的返回值

func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {
  var vowels = 0, consonants = 0, others = 0
  for character in string {
    switch String(character).lowercaseString {
    case "a", "e", "i", "o", "u":
      ++vowels
    case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
      "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
      ++consonants
    default:
    ++others
  }
  return (vowels, consonants, others)
}
let total = count("some arbitrary string!") println("\(total.vowels) vowels and \(total.consonants) consonants") // prints "6 vowels and 13 consonants"

 

1.2 函数的外部参数名 External Parameter Names

外部参数名用于给参数取别名,可以起到提示的作用。

定义方法:

func someFunction(externalParameterName localParameterName: Int) {
}

不使用外部参数名:

func join(s1: String, s2: String, joiner: String) -> String {
    return s1 + joiner + s2
}

join("hello", "world", ", ")

使用外部参数名:

func join(fromString s1: String, toString s2: String, withJoiner joiner: String)-> String {
    return s1 + joiner + s2
}

join(fromString: "hello", toString: "world", withJoiner: ", ")

 

1.3 速记外部参数名 Shorthand External Parameter Names

localParameterNameexternalParameterName 相同时,可以使用“#”(hash symbol)代替外部参数名

func join(#s1: String, #s2: String, #joiner: String)-> String {
    return s1 + joiner + s2
}

join(s1: "hello", s2: "world", joiner: ", ")

 

1.4 参数的默认值——默认值参数 Default Parameter Values

在定义函数的时候,可以给函数的参数设置一个默认值。当参数有默认值时,调用这个函数时可以可以忽略这个参数。一般情况下,请将有默认值的参数放在函数参数表的最后位置。

func join(fromString s1: String, toString s2: String, withJoiner joiner: String = “”) -> String{
    return s1 + joiner + s2
}

join(fromString: "hello", toString: "world", withJoiner: ", ") //hello,world
join(fromString: "hello", toString: "world") // "hello world"

 

1.5 默认值参数的外部变量名

当函数有默认值参数时,如果没有提供默认值参数的外部参数名,调用时,默认值参数会被编译器自动加上外部参数名(automatic external name),这个外部参数名实际上是“#”,即与内部参数名同名。

func join(s1: String, s2: String, joiner: String = "") -> String {
    return s1 + joiner + s2
}
join("hello", "world", joiner: "-") // "hello-world"

 

1.6 不定参数函数 Variadic Parameters

在参数后加上三个点(...)表示这个参数是可变参数,传递给可变参数的值由一组类似的值组成。

一个函数只能有一个可变参数,并且可变参数要出现在参数表的最后位置。如果一个函数既有默认参数值,又有可变参数,可变参数依然要放到参数表的最后位置。

//计算算术平均值
func arithmeticMean(numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
rithmeticMean(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    

 

1.7 可变参数和不可变参数 Constant and Variable Parameters

函数的参数默认是constant,尝试在函数体中修改不可变参数的值将导致编译时错误。

可变参数相当于给参数的值创建了一个可修改的副本(a new modifiable copy)。定义可变参数的方法是在参数名钱加上var关键字。

func alignRight(var string: String, count: Int, pad: Character) -> String {
  let amountToPad = count - countElements(string)
  for _ in 1...amountToPad {
    string = pad + string
  }
  return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"

 

1.8 In-Out 参数

C语言中,如果某个函数的作用是交换两个参数的值,那么应该传入这两个参数的指针。类似的,swift中,这两个参数要用inout关键字表示,函数外使用时,要加上&符号。例子如下:

func swapTwoInts1(var a: Int, var b: Int){
    let temp = a;
    a = b;
    b = temp;
}

func swapTwoInts2(inout a: Int, inout b: Int){
    let temp = a;
    a = b;
    b = temp;
}

var a = 10;
var b = 20;

swapTwoInts1(a, b)
println("a:\(a), b:\(b)")//a:10, b:20

swapTwoInts2(&a, &b)
println("a:\(a), b:\(b)")//a:20, b:10

 

1.9 函数类型 Function Types

每个函数都有类型,即函数类型(function type),它由参数类型和返回值类型复合而成。

例如:

func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int {
    return a * b
}

上面两个函数的类型都是 (Int, Int) -> Int

func printHelloWorld() {
    println("hello, world")
}

上面函数的类型是 () -> ()

 

1.10 函数类型的使用 Using Function Types

在swift中,函数类型的使用与其他类型一样。例如:

var mathFunction: (Int, Int) -> Int = addTwoInts
println("Result: \(mathFunction(2, 3))") //prints "Result: 5"

上面的代码定义了一个名为 mathFunction 的变量,他是一个 (Int, Int) -> Int 的函数类型,他的值为 addTwoInts 函数的引用。

函数 multiplyTwoInts 与 addTwoInts 具有相同的函数类型,相同类型的不同函数可以赋值给同一个变量,所以可以进行如下赋值:

 

mathFunction = mutiplyTwoInts
println(("Result: \(mathFunction(2, 3))") // prints "Result: 6"

 

你也可以定义函数类型为常量:

let anotherMathFunction = addTwoInts

 

1.11 函数类型参数 Function Types as Parameter Types

  你可以将函数类型如 (Int, Int) -> Int 的参数作为另一个函数的参数来使用,例如:

func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int){
    println("\(mathFunction(a, b))")        
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8"

  当执行语句 printMathResult(addTwoInts, 3, 5)  时,编译器将函数 addTwoInts 、3 和 5 传入 printMathResult 中,然后调用 addTwoInts 函数,得到结果8,最后打印出来。

 

1.12 函数类型返回值 Function Types as Return Type

  你可以将函数类型作为函数的参数类型来使用,如:

func stepForward(input: Int) -> Int {//向前一步
    return input + 1
}
func stepBackward(input: Int) -> Int {//向后一步
    return input - 1
}
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {//向前向后
    return backwards ? stepBackward : stepForward
}
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)

 

1.13 嵌套函数 Nested Function

  我们在上面所有看到的例子中的函数都是全局函数(global functions),你也可以在函数体内再定义函数,这就是嵌套函数(或许叫子函数比较形象)。

  嵌套函数默认对外部不可见,只能在包含它的函数中使用(be called and used by their enclosing function)(或者叫母函数比较形象)。一个母函数可以返回它的一个子函数,这样子函数就能在其他函数中使用了。

  例如:利用嵌套函数重写上面的 chooseStepFunction 函数

func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backwards ? stepBackward : stepForward
}
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)

 

posted @ 2015-01-08 14:22  action爱生活  阅读(342)  评论(0编辑  收藏  举报