【Swift】 - 函数(Functions)总结 - 比较 与 C# 的异同

1.0 函数的定义与调用( Defining and Calling Functions )

习惯了C#了语法,看到下面的这样定义输入参数实在感到非常别扭,func 有点 Javascript的感觉,还算习惯。函数调用与其他语言没什么区别

//有输入参数和返回值的函数
//输入参数为名name,数据类型为String
//返回值  String类型
func SayHello(name:String) ->String {
    return "Hello,"+name;
}
//调用函数
SayHello("_luo")

2.0 函数参数与返回值 ( Function Parameters and Return Values )

// 2.1 多重输入参数 ( Multiple Input Parameters )
func HalfOpenRangeLength(start:Int,end:Int) ->Int{
    return end - start;
}
// 2.2 无参函数 ( Functions Without Parameters )
func SayHelloWorld()->String{
return "Hello World";
}

// 2.3 无返回值函数 ( Functions Without Return Values )
func SayGoodbye(name:String){
    println("Goodbye,\(name)");
}

// 2.4 多重返回值函数 (Functions with Multiple Return Values )
//你可以用元组(tuple)类型让多个值作为一个复合值从函数中返回。
//计算一个字符串中元音,辅音和其他字母的个数
func Count(str:String)->(vowels:Int,consonants:Int,others:Int){
    var vowels=0,consonants=0,others=0;
    for item in str {
        switch String(item).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);
}

3.0 函数参数名称 ( Function Parameter Names )

上面的函数中的参数名仅在函数体中使用,不能这函数调用时使用,这种类型的参数名称为[局部参数名]。

与C#相比,Swift 有外部参数名。

外部参数名,是为了在调用函数时,可以指出各个实参的用途是什么。

(个人觉得实在是太不人性化了,为了知道这个参数的意义还要弄个外部参数名。C#就比较好了 在vs,只要写了注释,调用的时候就会显示各个参数的用途,顿时感觉到vs的强大)

// 3.1 外部参数名 ( External Parameter Names )
//外部参数名写在局部参数名之前,用空格分隔
//如果你提供了外部参数名,那么函数在被调用时,必须使用外部参数名。
//----没有外部参数名的写法👇-----
func Join(str1:String,str2:String,joinner:String)->String{
    return str1 + joinner + str2;
}
//当你调用这个函数时,这三个字符串的用途是不清楚的
Join("Hello", "World", ",")

//为了让这些字符串的用途更为明显,我们为Join函数添加外部参数名
func Join(string str1:String,toString str2:String,withJoiner joinner:String)->String{
    return str1 + joinner + str2;
}
//现在,你可以使用这些外部参数名以一种清晰地方式来调用函数了:
Join(string: "Hello", toString: "World", withJoiner: ",");

// 3.2 简写外部参数名 ( Shorthand External Parameter Names )
//如果你需要提供的外部参数名就是局部参数名,那么只写一次参数名并用#号作为前缀就可以了
func ContainsCharacter(#str:String,#char:Character)->Bool{
    for item in str{
        if(item == char){
            return true;
        }
    }
    return false;
}

ContainsCharacter(str: "klsdkfjoiwenklaskdf", char: "a")

// 3.3 默认参数值 ( Default Parameter Values )
// 3.4 默认值参数的外部参数名 ( External Names for Parameters with Default Values )
// 在大多情况下,给带默认值参数起一个外部参数名是很有用的。这样可以保证当函数被调用时,实參的意图是明显的
// 为了使定义外部参数名更加坚定,当你未给带默认值的参数提供外部参数名是,Swift 会自动提供外部名字。此时外部参数名字与局部名字是一样的,就像你已经在局部参数名前写了#一样
func Join(str1:String,str2:String,joinner:String=" ")->String{
    return str1 + joinner + str2;
}
Join("Hello", "World", joinner: "-")

// 3.5 可变参数 ( Variadic Parameters )
//通过这变量类型名后加...的方式来定义可变参数
//计算一组任意长度数字的算术平均数
func AritheticMean(numbers:Double...)->Double{
    var total:Double=0;
    for number in numbers{
        total += number;
        
    }
    return total / Double(numbers.count);
}
AritheticMean(1,2,2,1,23,22,12)
//注意:一个函数至多能有一个可变参数,而且它必须是参数表中的最后一个

// 3.6 常量参数和变量参数 ( Constant and Variable Parameters )
//函数参数默认上常量。试图这函数体中更改参数值将会导致变异错误,可以通过做参数名前加关键字var来定义变量参数
//使文字右对齐
func TextAlignRight(var str:String,totallength:Int,pad:Character)->String{
   
    let amountToPad = totallength - count(str);
    if(amountToPad<=0){
        return str;
    }
    for _ in 1...amountToPad{
        str=String(pad) + str;
    }
    return str;
}

TextAlignRight("loding", 10, "-")---------//"----loding"
TextAlignRight("Error", 10, "-")----------//"-----Error"

4.0 函数类型(Function Types)

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

例如:

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

这个例子中定义了两个简单的数学函数:addTwoInts 和 multiplyTwoInts。这两个函数都传入两个 Int类型, 返回一个合适的Int值。

这两个函数的类型是 (Int, Int) -> Int,可以读作“这个函数类型,它有两个 Int 型的参数并返回一个Int 型的值。”。

下面是另一个例子,一个没有参数,也没有返回值的函数:

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

这个函数的类型是:() -> (),或者叫“没有参数,并返回 Void 类型的函数”。没有指定返回类型的函数总返回 Void。在Swift中,Void 与空的元组是一样的。

接下来继续看函数类型的使用,可以发现很类似 C# 的委托了

// 4.1 使用函数类型 (Using Function Types)
//在 Swift 中,使用函数类型就像使用其他类型一样。例如,你可以定义一个类型为函数的常量或变量,并将函数赋值给它:
var mathFunction: (Int, Int) -> Int = addTwoInts
println("Result: \(mathFunction(2, 3))")
// prints "Result: 5"

//有相同匹配类型的不同函数可以被赋值给同一个变量,就像非函数类型的变量一样:
mathFunction = multiplyTwoInts
println("Result: \(mathFunction(2, 3))")
// prints "Result: 6"

//就像其他类型一样,当赋值一个函数给常量或变量时,你可以让 Swift 来推断其函数类型:
let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int

// 4.2 函数类型作为参数类型(Function Types as Parameter Types)
//你可以用(Int, Int) -> Int这样的函数类型作为另一个函数的参数类型。这样你可以将函数的一部分实现交由给函数的调用者。
//下面是另一个例子,正如上面的函数一样,同样是输出某种数学运算结果:
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
    println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8”

// 4.3 函数类型作为返回类型(Function Type as Return Types)
//你可以用函数类型作为另一个函数的返回类型。你需要做的是在返回箭头(->)后写一个完整的函数类型。
//下面的这个例子中定义了两个简单函数,分别是 stepForward 和stepBackward。stepForward 函数返回一个比输入值大一的值。stepBackward 函数返回一个比输入值小一的值。这两个函数的类型都是 (Int) -> Int:
func stepForward(input: Int) -> Int {
    return input + 1
}
func stepBackward(input: Int) -> Int {
    return input - 1
}
//下面这个叫做 chooseStepFunction 的函数,它的返回类型是 (Int) -> Int 的函数。chooseStepFunction 根据布尔值 backwards 来返回 stepForward 函数或 stepBackward 函数:
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}
//你现在可以用 chooseStepFunction 来获得一个函数,不管是那个方向:
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function

//上面这个例子中计算出从 currentValue 逐渐接近到0是需要向正数走还是向负数走。currentValue 的初始值是3,这意味着 currentValue > 0 是真的(true),这将使得 chooseStepFunction 返回 stepBackward 函数。一个指向返回的函数的引用保存在了 moveNearerToZero 常量中。

//现在,moveNearerToZero 指向了正确的函数,它可以被用来数到0:
println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
    println("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// 3...
// 2...
// 1...
// zero!

5.0 嵌套函数(Nested Functions)

在上面的例子中,你所见到的所有函数都叫全局函数(global functions),它们定义在全局域中。你也可以把函数定义在别的函数体中,称作嵌套函数(nested functions)。

默认情况下,嵌套函数是对外界不可见的,但是可以被他们封闭函数(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 = -4
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    println("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
println("zero!")
结果:
// -4... // -3... // -2... // -1... // zero!
posted @ 2015-07-10 00:12  10:00  阅读(1581)  评论(0编辑  收藏  举报