微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

你能在swift中强制执行一个typealias吗?

我试图强制执行一个由Int支持的简单类型,不会与其他Ints混淆.

假设您有以下typealiases:

typealias EnemyId = Int
typealias WeaponId = Int

我希望以下内容有编译错误

var enemy: EnemyId = EnemyId("1")
enemy = WeaponId("1") // this should fail

我想失败的那一行应该失败,因为两种类型(EnemyId和WeaponId)是不同的类型.

实现这一目标最好,最干净的方法是什么?

UPDATE

在查看了答案和评论之后,我想用枚举添加我想出的内容

enum Enemy {
    case id(Int)
    var id: Int {
        switch self {
        case .id(let i):
            return i
        }
    }
}
let enemy = Enemy.id(1)
print("enemy: \(enemy.id)")

目前,Mattt的答案要短得多,而且更符合您对Swift的期望.

更新#2

我还没有访问swift 4.1所以我必须执行以下操作:

struct EnemyId : Hashable {
    private let value: Int

    init(_ value: Int) {
      self.value = value
    }

    init?(_ string:String) {
      guard let value = Int(string) else { return nil }
      self.init(value)
    }

    static func ==(_ lhs: EnemyId,_ rhs: EnemyId) -> Bool {
      return lhs.value == rhs.value
    }

    var hashValue: Int {
      return value.hashValue
    }
  }

然而,事实证明我的解析添加了几百毫秒,因此我不得不恢复到类型,但它非常接近我想要的.

解决方法

Swift没有(还有?)具有newtype的概念 – 基本上是一个不透明的类型,它返回了与原始类型相同的值.

你可以做的是使用包裹原始类型的1字段结构. 1字段结构没有性能损失,同时为您提供了一个独特的类型,带有更多的语义值(感谢@RobNapier提供有关Hashable的优秀提示):

struct EnemyId: Hashable {
    private let value: Int

    init(_ value: Int) { self.value = value }

    static func ==(_ lhs: EnemyId,_ rhs: EnemyId) -> Bool {
        return lhs.value == rhs.value
    }

    var hashValue: Int {
        return value.hashValue
    }
}

struct WeaponId: Hashable {
    private let value: Int

    init(_ value: Int) { self.value = value }

    static func ==(_ lhs: WeaponId,_ rhs: WeaponId) -> Bool {
        return lhs.value == rhs.value
    }

    var hashValue: Int {
        return value.hashValue
    }
}

像这样的类型可以像Int那样在许多地方使用,而不同.当然,您可以根据需要添加更多协议一致性.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐