将动态类型作为参数传递

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

以上是关于将动态类型作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

将模板化智能指针类型作为模板参数传递

如何将浮点矩阵作为 2D 纹理传递给片段着色器?

将接口从片段传递到kotlin中的活动

C#:将枚举类型作为参数传递

在C代码中将结构体变量作为参数传递效率忒低

如何绕过将数据模型传递给片段参数以避免事务太大异常?