Swift中的函数引用

不同于大部分的编程语言,Swift中函数(Function)不仅允许重载(Overload),而且是由函数名称(Function Name)、参数标签(Argument Label)、参数类型(Parameter Type)和返回值类型(Return Type)共同确定的。比如——

func f() {}
func f() -> Int { return 0 }
func f() -> String { return "" }
func f(_ a: Int) {}
func f(_ a: String) {}
func f(a: Int) {}
func f(a: String) {}

全都可以同时存在。

在使用时,除了通常所需的函数名称和参数列表之外,有时还需要额外指定返回值类型才能避免歧义。在上述函数定义之后,单独使用——

f()

是无法通过编译的(因为f()有多种返回值类型的版本),而是需要使用——

f() as Void
let _: Void = f()
f() as Int
let _: Int = f()
f() as String
let _: String = f()

来进行区分。

所有的函数都可以使用闭包来进行引用。如果一个函数没有被重载,那么使用它的名字就能生成一个闭包,例如——

func g(b: Bool) -> Bool {
    return !b
}
let g0 = g

g(b: false) == true
g(b: true) == false
g0(false) == true
g0(true) == false

其中g0的类型为(Bool) -> Bool。需要注意的是,使用g的时候并没有加上后续的括号对,这与正常的函数调用有所区别。同时,由于g0是一个闭包,调用时不再使用参数标签。

当函数被重载时,我们可能需要在指定函数名称之外指定参数标签、参数类型和/或返回值类型才能引用相应的函数。其中参数类型和返回值由闭包类型指定,而参数标签跟随函数名称进行指定。例如——

let f0 = f as () -> Void
let f1 = f as () -> Int
let f2 = f as () -> String
let f3 = f(_:) as (Int) -> Void
let f4 = f(_:) as (String) -> Void
let f5 = f(a:) as (Int) -> Void
let f6 = f(a:) as (String) -> Void

如果闭包类型部分(参数类型+返回值类型)没有歧义,则可以将其省略。

方法(Method)是特殊的函数,其也可被引用为闭包。例如——

struct S {
    static func h() {}
    func h() {}
}
let s = S()
let h0 = S.h
let h1 = s.h
let h2 = S.h(s)

其中h0引用了静态方法S.h()h1h2引用了实例方法s.h()。值得一提的是,生成h2时存在签名为static func h(_ self: S) -> () -> Void的方法S.h(s),但是实际上并不能通过S.h(_:)来引用这个方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容