如何在Swift中使用动态类型调用通用函数

8

假设我有一个名为 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个回答

2
问题在于这个:
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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接