跳转至

函数

函数

目录


1.函数定义与调用

1
2
3
4
5
6
7
8
9
// 定义函数
func sayHello(name:String)-> String {
    return "hello,"+name
}

//调用函数

println(sayHello("malinkang"))
//hello,malinkang

2.函数参数

2.1多个参数

1
2
3
4
5
6
func add(a:Int,b:Int) -> Int {
    return a + b
}

println(add(4,8))
// 输出12

2.2没有参数

1
2
3
4
5
func sayHelloWorld() -> String {
    return "Hello,World"
}

println(sayHelloWorld())

2.3外部参数名

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

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

1
2
3
4
func someFunction(externalParameterName localParameterName: Int) {
    // function body goes here, and can use localParameterName
    // to refer to the argument value for that parameter
}
如果你提供了外部参数名,那么函数在被调用时,必须使用外部参数名。

1
2
3
4
5
6
7
8
func sayHello(name localname:String)-> String {
    return "hello,"+localname// 不能使用name
}

//调用函数

println(sayHello(name:"malinkang"))
//hello,malinkang

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

1
2
3
4
5
6
7
8
9
// 定义函数
func sayHello(#name:String)-> String {
    return "hello,"+name// 不能使用name
}

//调用函数

println(sayHello(name:"malinkang"))
//hello,malinkang

2.4默认参数值

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

Swift自动为默认参数提供了外部参数名,当函数调用时,外部参数名必须使用。

func add(a:Int,b:Int = 1,c:Int) -> Int{
    return a + c + b
}

println(add(1,b: 3,2))
//输出 6

func add(a:Int,c:Int,b:Int = 1) -> Int{
    return a + c + b
}

println(add(1,2))
//输出 4


func add(a:Int,c:Int,b:Int = 1) -> Int{
    return a + c + b
}

println(add(1,2,b:4))
// 输出 7


func add(a:Int,c:Int = 2,b:Int = 1) -> Int{
    return a + c + b
}

println(add(1))
// 输出 4

2.5可变参数

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

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

func arithmeticMean(numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }

    println(numbers[0])// 可以使用下标访问
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
//3.0
arithmeticMean(3, 8, 19)
//10.0

一个函数至多能有一个可变参数,而且它必须是参数表中最后的一个。

参数默认是常量,所以不能改变参数的值。要想改变参数的值,必须将参数定义为变量。

1
2
3
4
5
func addOne(var a:Int) -> Int{
    return a++;
}

addOne(1)

2.6输入输出参数

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

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

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

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

func addOne(inout a:Int) -> Int{
    return ++a;
}

var a = 10

println(addOne(&a))
// 输出11
println(a)
// 输出 10

3.函数返回值

3.1没有返回值

1
2
3
4
5
func sayGoodbye(){
    println("Goodbye")
}

sayGoodbye()

严格意义上说,虽然没有返回值被定义,没有定义返回类型的函数会返回特殊的值Void,它其实是一个空的元组,没有任何元素,可以写成().

被调用时,一个函数的返回值会被忽略:

func printAndCount (stringToPrint:String) -> Int {
    println(stringToPrint)

    return count(stringToPrint)
}

func printWithoutCounting(stringToPrint:String){
    printAndCount(stringToPrint)
}

var a = printAndCount("hello, world")
// 打印 "hello, world" 并且返回 12
printWithoutCounting("hello, world")
//打印 "hello, world" 不返回值

3.2多个返回值

可以用元组类型让多个值作为一个复合值从函数中返回。

下面定义一个count函数,用来计算字符串中元音辅音和其他字母的个数。

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)
}

4.函数类型

每个函数都有特定的函数类型,由函数的参数类型和返回类型组成。

1
2
3
func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}

这个函数的类型是(Int,Int) -> Int

1
2
3
func printHelloWorld() {
    println("hello, world")
}

这个函数的类型是() -> ()

4.1使用函数类型

使用函数类型和使用其他类型一样,可以定义一个类型为常量或变量,并将函数赋值给它。

1
2
3
4
5
6
7
func add(a:Int,b:Int) ->Int{
    return a + b
}
// var anotherAdd:(Int,Int) -> Int =add
var anotherAdd = add

println(anotherAdd(1,2))

4.2函数类型作为参数类型

1
2
3
4
5
6
func printResult(a:Int,b:Int,add:(Int,Int)->Int = add){
    println("Result=\(add(1,2))")
}

printResult( 2, 1)
//Result=3

4.3函数类型作为返回值

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)

while currentValue != 0 {
    println("\(currentValue)")
    currentValue=moveNearerToZero(currentValue)
}
//
//3
//2
//1

4.4嵌套函数

你可以把函数定义在别的函数体内部,上面的例子可以修改为

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)

while currentValue != 0 {
    println("\(currentValue)")
    currentValue=moveNearerToZero(currentValue)
}
//
//3
//2
//1

注意,如果参数有修饰符,返回里也需要在参数的类型前面明确指定修饰符,以符合内部的定义。

1
2
3
4
5
func makeIncrementor(addNumber: Int) -> ((inout Int) -> ()) {
    func incrementor(inout variable: Int) -> () {
        variable += addNumber;
    }
return incrementor; }

评论