&引用;函数的模糊使用“;在Swift中重载泛型函数时

&引用;函数的模糊使用“;在Swift中重载泛型函数时,swift,generics,overloading,Swift,Generics,Overloading,下面你会看到一个游乐场,在那里我试图说明我的问题。我有一个类(Foo),其中包含一些重载的泛型方法(bar()),其返回类型取决于泛型参数。我有三种方法: 必须返回特定类型的子类(在下面的示例中称为BaseClass) 另一个必须返回此特定类型实例的数组 如果其他两个条件未满足,则应将最后一个条件用作默认条件 当我调用该方法时,问题就出现了。即使我告诉编译器我期望的类型是什么,它也会给我错误使用bar() import UIKit class BaseClass { require

下面你会看到一个游乐场,在那里我试图说明我的问题。我有一个类(
Foo
),其中包含一些重载的泛型方法(
bar()
),其返回类型取决于泛型参数。我有三种方法:

  • 必须返回特定类型的子类(在下面的示例中称为
    BaseClass
  • 另一个必须返回此特定类型实例的
    数组
  • 如果其他两个条件未满足,则应将最后一个条件用作默认条件
当我调用该方法时,问题就出现了。即使我告诉编译器我期望的类型是什么,它也会给我错误使用bar()

import UIKit

class BaseClass {
    required init() {}
}

class Foo {

    // 1
    func bar<T: BaseClass>() -> T? {
        // Just a default implementation, it should do real work inside
        return T()
    }

    // 2
    func bar<T: BaseClass>() -> [T]? {
        // Just a default implementation, it should do real work inside
        return []
    }

    // 3
    func bar<T>() -> T? {
        // Just a default implementation, it should do real work inside
        return "Test" as? T
    }
}

let foo = Foo()

// Should call "1", because it return type is BaseClass
let baseClassObject: BaseClass? = foo.bar()

// Should call "2", because it return type is [BaseClass]
let baseClasArray: [BaseClass]? = foo.bar()

// Should call "3", because it return type is neither BaseClass nor [BaseClass]
let anyOtherObject: String = foo.bar()

第3项导致与其他功能冲突


这是因为也可以是BaseClass类型和[BaseClass]类型。编译器只会看到一个接口“throw anythine in here”,它将与任何更具体的特定级别冲突。

第3项导致与其他函数冲突


这是因为也可以是BaseClass类型和[BaseClass]类型。编译器只看到一个接口“throw anything in here”,它将与任何更具体的特定级别冲突。

要对此进行扩展,为什么要
让baseClassObject:BaseClass?=foo.bar()
自动调用第一个
bar
?是的,我知道冲突来自最后一个。我想编译器知道我调用第一个函数是因为返回类型。我认为编译器会从更具体的检查到不太具体的检查,并使用更具体的检查。至少在其他情况下是这样的。请,@PEEJWEEJ,看看我的问题更新。为了进一步说明这一点,为什么
应该让baseClassObject:BaseClass?=foo.bar()
自动调用第一个
bar
?是的,我知道冲突来自最后一个。我想编译器知道我调用第一个函数是因为返回类型。我认为编译器会从更具体的检查到不太具体的检查,并使用更具体的检查。至少在其他情况下是这样的。请,@PEEJWEEJ,查看我的问题更新。
import UIKit

class BaseClass {
    required init() {}
}

class Foo {

    // 1
    func bar<T: BaseClass>(param: T) -> String {
        return "I am BaseClass"
    }

    // 2
    func bar<T: BaseClass>(param: [T]) -> String {
        return "I am [BaseClass]"
    }

    // 3
    func bar<T>(param: T) -> String {
        return "I am other thing"
    } 
}

let foo = Foo()

// It prints "I am BaseClass"
foo.bar(BaseClass())

// It prints "I am [BaseClass]"
foo.bar([BaseClass(), BaseClass()])

// It prints "I am another thing"
foo.bar(NSObject())