如何在Swift中调用动态类型的泛型函数

时间:2016-03-31 17:31:25

标签: swift generics

说我有一个协议Fooable

protocol Fooable {}

现在我需要在通用函数中使用Fooable类型:

func fooingAround<FooableType: Fooable>(withType: FooableType.Type) {}

当我用Fooable类型调用函数时,这很好用:

struct Foo: Fooable {}
fooingAround(Foo.self) // works fine

但是,我需要检索我从其他地方移交给函数的Fooable类型。这是编译器失败的地方:

let fooableType: Fooable.Type = // obtain from somewhere else
fooingAround(fooableType) // compiler error: "Cannot invoke 'fooingAround' with an argument list of type '(Fooable.Type)'"

具体来说,我从描述API端点的枚举中获取Fooable.Type,其中每个端点由不同的Fooable类表示。

我认为问题出现是因为我动态地获取了一个类型,所以在编译时不能强类型。

有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

问题在于:

let fooableType: Fooable.Type = // obtain from somewhere else

...正在将您想要存储在该变量中的信息精确地遗忘,即符合Fooable的具体类型是什么。请考虑以下代码编译:

protocol Fooable {}

func fooingAround<FooableType: Fooable>(withType: FooableType.Type) {}

struct Foo: Fooable {}
fooingAround(Foo) // works fine

let foo = Foo()
let fooableType /* do not cast here */ = foo.dynamicType

fooingAround(fooableType) // also works fine

...这意味着您必须找到一种方法直接将类型信息传递到函数调用中而不进行强制转换。

根据您所考虑的fooingAround种类,例如,您可以按以下方式扩展Fooable

extension Fooable {

    func fooingAround() {
        /* do some fooing with */ self.dynamicType // which is the Foo.Type when called on the `foo` value
    }
}

foo.fooingAround()