你能在 swift 中强制执行类型别名吗 [英] Can you enforce a typealias in swift

查看:20
本文介绍了你能在 swift 中强制执行类型别名吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to enforce a simple type backed by an Int does not get mixed up with other Ints.

假设您有以下类型别名:

Say you have the following typealiases :

typealias EnemyId = Int
typealias WeaponId = Int

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

I would like the following to have a compiler error:

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

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

The line I want to fail, should fail, because the two types (EnemyId and WeaponId) are different types.

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

What would be the nicest, cleanest way of achieving this?

更新

在查看答案和评论后,我想添加我使用枚举的想法:

After reviewing the answers and comments, I wanted to add what I came up with using enums:

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 的期望.

Currently Mattt's answer is much shorter and more in line with what you expect in Swift.

更新 #2

我还无法访问 swift 4.1,所以我必须执行以下操作:

I do not yet have access to swift 4.1 so I had to do the following:

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

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

It however turned out to add a couple of hundreds of milliseconds to my parsing, therefore I had to revert to the typealias, but it was very close to what I wanted.

推荐答案

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

Swift doesn't (yet?) have the concept of newtype - basically an opaque type backstored with the same values as the original type.

您可以做的是使用包装原始类型的 1-field 结构.1 字段结构没有性能损失,同时为您提供一个独特的类型来处理,携带更多的语义值(感谢 @RobNapier 关于 Hashable 的重要提示):

What you could do, is to use 1-field structs that wrap the original type. 1-field structs have no performance penalty while giving you a distinct type to work with, carrying more semantical value ( thanks @RobNapier for the great tip regarding 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 一样,但又有所不同.当然,您可以根据需要添加更多协议一致性.

Types like this can be used in many places as an Int would do, while being different. Of course you could add more protocols conformance, based on the needs.

这篇关于你能在 swift 中强制执行类型别名吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆