swift-only 八条精选首页投稿(暂停使用,暂停投稿)iOS Developer

2.5 swift函数的类型

2016-07-22  本文已影响91人  八条8tiao

我们之前把函数看做是代码的逻辑单元,实际上不仅如此,函数还和我们用var或let定义的东西一样,可以被赋值并且有类型呢!怎么样?是不是感觉函数这家伙看似忠厚老实,其实背后还有故事?确实,函数背后面还有大大的故事呢。

1、函数是个什么

func printStr(str: String) {
    print(str)
}

let anotherPrintStr = printStr
anotherPrintStr("Hello world") // 在控制台输出 "Hello world"

我们首先定义了一个函数 printStr 接着我们把它赋值给了一个用let声明的常量 anotherPrintStr,然后,然后,然后 anotherPrintStr 居然可以被当做一个函数进行调用了。这篇代码看起来还是不够明显,让我们继续研究一下,我们应该还记得我们之前提前过的 类型推断 机制吧,既然swift是一们静态的强类型语言,那么它是不会允许常量 anotherPrintStr 没有类型而存在,此时一定是类型推断机制在暗中给 anotherPrintStr 赋予了类型,我们可以通过xcode帮助我们揪出这个类型是什么,这个类型就是: (String) -> Void

函数的类型是由 参数类型与返回值类型共同决定的,Void代表函数没有返回值,如果一个函数既没有参数也没有返回值,那么该函数的类型应该是 () -> Void

那么也就是说我们可以用显示声明的方式来定义anotherPrintStr了。

let anotherPrintStr: (String) -> Void = printStr
anotherPrintStr("Hello world") // 在控制台输出 "Hello world"

这个时候我们已经完全明白anotherPrintStr不过是一个函数类型的常量吗,但是函数printStr到底是什么呢?我们尝试用函数类型重新定义一下printStr。

let printStr: (String) -> Void = {str in
    print(str)
}

printStr("Hello world") // 在控制台输出 "Hello world"

通过这段代码我们可以这样理解printStr,它是一个用let声明的常量,类型是函数类型 (String) -> Void 它的值是一段可以执行的代码体(这是闭包的定义方式,我们可以暂时忽略)。也就是说和一个整形常量的区别在于,printStr的值可以被执行。

2、函数是一类公民

我们可能早就听说了,swift的函数是一类公民,这其实说的是函数与swift的其他类型一样,并没有受到歧视,而是得到了平等的对待,这包括赋值,传递,作为参数和返回值等。

func printStr(str: String) {
    print(str)
}

func anewFunc(perform: (String) -> Void) -> (String) -> Void {
    return perform
}

anewFunc(printStr)

我们定义了一个函数 anewFunc 它接收一个 (String) -> Void 类型,并返回一个 (String) -> Void 类型。我们可以把函数作为参数传递给 anewFunc ,而该函数又将其做为返回值。

3、这一切都是为了啥

我们现在承认 函数确实能做为另外一个函数的参数和返回值,可是这折腾来折腾去的是为了啥呢?我想这应该有两点原因。

上一篇 下一篇

猜你喜欢

热点阅读