2016-04-18 72 views
0

下面您会看到一个游乐场,我试图说明我的问题。我有一个类(Foo),其中一些重载的泛型方法(bar<T>())的返回类型取决于泛型参数。我有3种方法:当在Swift中重载泛型函数时,“Ambiguos使用函数”

  • 一个必须返回一个特定类型的子类(在下面的例子中它被称为BaseClass
  • 其他人必须返回此特定类型的实例的Array
  • 如果不满足其他两个条件,则最后一个应该用作默认值。

问题来了,当我打电话的方法。即使我告诉编译器我期待的类型是什么,它给我错误Ambiguos使用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() 

在我看来,编译器应该知道什么方法调用,因为我告诉它的返回类型,对不对?这是泛型的一个限制还是我错过了什么?

在此先感谢。

更新4月19日

在他们说了,他说的矛盾来,因为“BaseClass的”可以被解释为BaseClass而且作为T。但在这个修改后的游乐场中,编译器确实推断出哪种方法正确使用。有什么区别吗?我这里有同样的冲突?:

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()) 

回答

2

号码与其他功能

这是因为< T>也可能是类型的BaseClass的和类型[BaseClass的]的3个起因冲突。编译器只是看到一个“在这里抛出任何东西”的接口,这将与任何更具体的特定级别相冲突。

+0

为了扩大这个,为什么要'let baseClassObject:BaseClass? = foo.bar()'自动调用第一个'bar'? – BallpointBen

+0

是的,我知道冲突来自最后一个。我认为编译器知道我正在调用第一个,因为返回类型。我认为编译器会从更具体到更具体的方面进行检查,并使用更具体的方法。至少,在其他情况下它是这样做的。请@PEEJWEEJ查看我的问题更新。 – manueGE