Swift:方法重载只在返回类型上有所不同

mar*_*314 6 ios swift swift2

我一直在看Swift类,其中定义了两种方法,它们的返回类型不同.我不习惯使用允许这种语言的语言(Java,C#等),所以我去寻找描述它如何在Swift中工作的文档.我在任何地方都找不到任何东西.我本来期望在Swift书中有关于它的整个部分.这记录在哪里?

这是我正在谈论的一个例子(我正在使用Swift 2,FWIW):

class MyClass {
    subscript(key: Int) -> Int {
        return 1
    }

    subscript(key: Int) -> String {
        return "hi"
    }

    func getSomething() -> Int {
        return 2
    }

    func getSomething() -> String {
        return "hey"
    }
}
Run Code Online (Sandbox Code Playgroud)

测试:

    let obj = MyClass()    

    //let x = obj[99]
    // Doesn't compile: "Multiple candidates fail to match based on result type"

    let result1: String = obj[123]
    print("result1 \(result1)")  // prints "result1 hi"

    let result2: Int = obj[123]
    print("result2 \(result2)") // prints "result2 1"

    //let x = obj.getSomething()
    // Doesn't compile: "Ambiguous use of 'getSomething'"

    let result3: String = obj.getSomething()
    print("result3 \(result3)")  // prints "result3 hey"

    let result4: Int = obj.getSomething()
    print("result4 \(result4)") // prints "result4 2"
Run Code Online (Sandbox Code Playgroud)

rin*_*aro 8

这记录在哪里?

至于subscript:

语言参考/声明/下标声明

只要参数或返回类型与您正在重载的参数或返回类型不同,您就可以在声明它的类型中重载下标声明.

语言指南/下标/下标选项

类或结构可以根据需要提供尽可能多的下标实现,并且将基于在使用下标的点处的下标括号内包含的值或值的类型来推断要使用的适当下标.

我找不到任何关于重载方法或函数的官方文档.但在Swift博客中:

使用Swift REPL/Redefinition或Overload重新定义所有内容?

请记住,即使两个签名仅在返回类型上有所不同,Swift也允许函数重载.


fqd*_*qdn 6

函数的类型由其参数的类型和返回值的类型决定,编译器可以根据类型消除类似命名函数的歧义 - 从您的示例:

subscript(key: Int) -> Int {
    return 1
}
Run Code Online (Sandbox Code Playgroud)

......有类型 (Int) -> Int

subscript(key: Int) -> String {
    return "hi"
}
Run Code Online (Sandbox Code Playgroud)

......有类型 (Int) -> String

- 因此虽然它们的名称相似,但编译器可以通过如何分配返回值来推断调用哪一个(或者因为这是a subscript,通过分配给该下标的值)

继续:

func getSomething() -> Int {
    return 2
}
Run Code Online (Sandbox Code Playgroud)

......有类型 () -> Int

func getSomething() -> String {
    return "hey"
}
Run Code Online (Sandbox Code Playgroud)

......有类型 () -> String

注意:如果你没有为编译器提供足够的信息来推断你正在调用哪个函数,那么你可能会遇到麻烦的地方,例如,如果你只是在getSomething()没有做任何返回值的情况下调用它,它会抱怨ambiguous use of 'getSomething'

编辑 - 啊,我在你的示例代码中看到你实际上提供了一个例子,这是这种情况:)通过将返回值赋给一个你没有指定类型的常量(let x = getSomething())没有足够的信息编译器来整理你正在调用的函数

编辑 编辑 - 请注意,在我开始说" 编译器可以通过类型消除类似命名函数的歧义 "时,函数名称由以下因素确定:(1)函数的标识符,以及(2)函数外部参数的标识符名称 - 例如,虽然以下两个函数都具有相同的类型和函数标识符,但它们是不同的函数并具有不同的函数名称,因为它们的外部参数名称使用的标识符不同:

func getSomething(thing: String, howMany: Int) -> String
Run Code Online (Sandbox Code Playgroud)

...有类型(String, Int) -> String,并命名getSomething(_:howMany:)

func getSomething(thing: String, howManyTimes: Int) -> String
Run Code Online (Sandbox Code Playgroud)

...有类型(String, Int) -> String,并命名getSomething(_:howManyTimes:)