swift - 如何在 Swift 中多态地转换为类类型?

标签 swift swift3

这里,layEgg() 想要重用 chickenFactory(Chicken.Type)。问题是layEgg返回Self?这样我就可以得到任何类型的实例 this is or nil。

但是,chickenFactory 返回一个 Chicken,需要将其转换为我的任何类型。

enum BiologicalGender : String {
    case male = "male"
    case female = "female"
}

class Chicken {
    let gender : BiologicalGender

    required init (_ gender : BiologicalGender) {
        self.gender = gender
    }

    class func chickenFactory(_ chickenType : Chicken.Type) -> Chicken {
        if (arc4random_uniform(2) == 0) {
            return chickenType.init(.male)
        } else {
            return chickenType.init(.female)
        }
    }

    func layEgg() -> Self? {
        if (self.gender == .female) {
            return Chicken.chickenFactory(type(of:self)) // need a cast here
        } else {
            return nil
        }
    }
}

如何进行多态转换?

最佳答案

问题是 chickenFactory(_:) 说它接受 Chicken.Type 类型的类型作为参数并输出 Chicken< 的实例。输出的实例不必是您传入的类型(例如,当您输入 ChickenSubclass.self 类型时,它可以输出 Chicken 的实例) .

您想要的不是类型转换,而是一种表明输出的实例与您输入的类型相同的方式。为了表达这一点,您可以使用通用占位符:

class func chickenFactory<T : Chicken>(_ chickenType : T.Type) -> T {
    if (arc4random_uniform(2) == 0) {
        return chickenType.init(.male)
    } else {
        return chickenType.init(.female)
    }
}

现在

func layEgg() -> Self? {
    if (self.gender == .female) {
        return Chicken.chickenFactory(type(of: self))
    } else {
        return nil
    }
}

编译得很好,因为编译器知道类型 type(of: self) 的实例可以从返回 Self? 的函数中返回。

尽管如此,chickenFactory(_:) 的类型参数似乎是多余的,您可以通过使用 self 在静态范围内:

class func chickenFactory() -> Self {
    if (arc4random_uniform(2) == 0) {
        return self.init(.male)
    } else {
        return self.init(.female)
    }
}

func layEgg() -> Self? {
    if (self.gender == .female) {
        return type(of: self).chickenFactory()
    } else {
        return nil
    }
}

关于swift - 如何在 Swift 中多态地转换为类类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41616479/

相关文章:

ios - 如何在多个 View Controller 之间发送数据 swift 3

ios - hidesBarsOnTap - 导航栏隐藏/显示事件?

xcode - 在 Swift 中以编程方式切换 View

ios - 2016 年 12 月 15 日,星期四 05 :00:00 EST to Date swift 3 but returns nil

ios - 使用 Alamofire + SwiftyJSON 无法将数据加载到 UITableView

swift - 即使导航 Controller 是 Root View ,如何将引导屏幕放在屏幕上

ios - 将核心数据数据库从一台设备传递/导出到另一台设备

swift - 没有这样的模块 'SwiftyDropbox'

ios - 如果日期是一个月的开始,则获取当前周的所有日期返回不正确

swift - Firebase 检查帐户是否被禁用