将动态类型作为参数传递
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将动态类型作为参数传递相关的知识,希望对你有一定的参考价值。
我想要完成的是将动态类型的对象作为参数传递给泛型函数。我能用type(of:)
看到我想要的正确类型,但我无法将其作为参数传递,因为在泛型函数中我仍然得到静态类型。这是我想要做的一个例子:
protocol SomeUsefulProtocol {}
struct MyType1: SomeUsefulProtocol {}
struct MyType2: SomeUsefulProtocol {}
let objects: [SomeUsefulProtocol] = [MyType1(), MyType2()]
let someClosureToWorkWithMyType: Any = { (object: MyType1) in
//Do some great things
}
func someMethod<T>(type: T.Type, object: Any) {
typealias ClosureType = (T) -> Void
if let closure = someClosureToWorkWithMyType as? ClosureType, let object = object as? T {
closure(object)
}
}
for object in objects {
someMethod(type: type(of: object), object: object)
}
这里我希望在对象具有类型“MyType1”时调用闭包someClosureToWorkWithMyType,但在方法内部,对象的类型是静态类型(SomeUsefulProtocol)。
答案
这里的问题是object
被宣布为协议SomeUsefulProtocol
的一个实例。协议的实例不是任何特定的具体类型,并且可以是潜在的许多具体类型之一。
Swift的泛型系统在编译时需要已知的具体类型来创建正确的特化。有许多博客文章和StackOverflow问题和答案深入研究了尝试将Swift协议和Swift泛型一起使用的棘手(通常是徒劳的)。
在您的具体示例中,您的方法可以通过以下两种方式之一工作:要么不将object
声明为协议实例,而是将其设置为具体类型,例如:
let object: MyType = MyType()
或者将其声明为原样,但在将其传递给函数时将其强制转换为具体类型,例如:
(object as? MyType).flatMap{ someMethod(type: type(of: $0), object: $0) }
以上是关于将动态类型作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章