说我有一个协议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
类表示。
我认为问题出现是因为我动态地获取了一个类型,所以在编译时不能强类型。
有办法解决这个问题吗?
答案 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()