swift 3向下转换为动态类

标签 swift generics protocols downcast

我正在尝试创建几个相互依赖的对象,它们必须有一种方法可以直接向下转换另一个对象的具体类。像这样:

protocol aProt
{
    var bVar:bProt! { get set }
}

protocol bProt
{
    var aVar:aProt!  { get set }
}

class a: aProt
{
    var bVar: bProt!
    func bConcrete() -> b {
        return bVar as! b
    }
}

class b: bProt
{
    var aVar: aProt!
    func aConcrete() -> a {
        return aVar as! a
}

现在,问题是我希望此行为 (func aConcrete(),func bConcrete()) 由 a 和 b 的子类继承。然后我认为做到这一点的完美方法是使用泛型,但是......没有办法做到这一点。

a 类:aProt { var bVar: 保护! func bConcrete() -> T { 返回 bVar 作为!吨 }

class b: bProt
{
    var aVar: aProt!
    func aConcrete<T>() -> T {
        return aVar as! T
}

你可以这样做,但是当你必须使用它时,无论如何你都必须向下转型变量,所以没有办法以干净的方式做到这一点:

let aObject = a()
let bSubclassObject = a.bConcrete() // The compiler complains it cannot infer the class of T
let bSubclassObject = a.bConcrete() as! bSubclass // this works, but this is exactly which I wanted to avoid... :(

最佳答案

定义泛型函数并添加 where 到 T:

protocol aProt {
    var bVar: bProt! { get set }
}

protocol bProt {
    var aVar:aProt!  { get set }
}

class a: aProt {
    var bVar: bProt!
    func bConcrete<T: b>(_ type: T.Type) -> T? {
        return bVar as? T
    }
}

class b: bProt {
    var aVar: aProt!
    func aConcrete<T: a>(_ type: T.Type) -> T? {
        return aVar as? T
    }
}

class a1: a { }
class b1: b {
    var fullName: String = "new object"
}

let aObj = a()
aObj.bVar = b1()
let bObj = aObj.bConcrete(b1.self)
bObj?.fullName

根据您的要求,调用 bConcrete(b1.self) 可能仍然不够好,但至少您需要知道您期望返回的数据类型。

关于swift 3向下转换为动态类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41377487/

相关文章:

Java 接口(interface) - 泛型

来自子类的 C# 泛型类型参数,可能吗?

swift - 使用 EXC_BAD_INSTRUCTION 在空扩展中断中声明符合 @objc 协议(protocol)

ios - AudioKit:我可以在不调用 AudioKit.stop() 的情况下禁用 AKMicrophone 吗?

swift - AWS iOS 开发工具包 : Using both S3 and Mobile Analytics in two different regions

ios - 问题 - DBAccess ORM 使用 swift 声明 bool 类型创建表

ios - 如何使用委托(delegate)/协议(protocol)在多个 View Controller 之间传递值

swift - 用 swift 替换 Spritekit 中的场景

java - 为什么 Java 的 TreeSet<E> remove(Object) 不带 E

protocols - 种子是如何工作的?