【问题标题】:It seems Swfit.AnyHashable is not casing (as!, as?, as) properly with enums似乎 Swfit.AnyHashable 不能正确地使用枚举(as!,as?,as)
【发布时间】:2017-09-26 22:37:11
【问题描述】:

这是一个 AnyHashable 不支持枚举类型转换的简单案例。

enum testEnum: String {
    case Test
}

let myObject: AnyHashable = testEnum.Test as AnyHashable
let newObject = myObject as? testEnum

在这种情况下,newObject 将返回 nil。如果我改为这样做

let newObject = (myObject as? AnyObject) as? testEnum

它会很好地投射。

我已经尝试过使用结构、自定义类和字符串,它们都正确转换。例如这行得通。

let myObject: AnyHashable = "Test" as AnyHashable
let newObject = myObject as? String

这是 swift 中的错误还是我在这里没有正确执行此操作。

我在 Swift 3.2 和 Swift 4 中尝试过这个。

【问题讨论】:

  • 您应该使用Any 而不是AnyHashable。顺便说一句,以大写字母开头的枚举命名和以小写字母开头的案例是 Swift 约定

标签: swift enums hashable


【解决方案1】:

AnyHashableexplicitly type-erases:

AnyHashable 类型将相等比较和散列操作转发到底层可散列值,隐藏其特定的底层类型。

这恰好适用于某些类型的事实是令人惊讶的事实,而不是它对于枚举失败。我希望这是一种有助于字典的性能优化。但这不是您期望使用AnyHashable 的方式。预期的用法是用AnyHashable.init 初始化它,而不是as AnyHashable

你的意思是这样的:

enum TestEnum: String {
    case test
}

let myObject = AnyHashable(TestEnum.test)
myObject.base               // => test (as an Any)
myObject.base as? TestEnum  // => Optional<TestEnum>(.test)

请注意,AnyHashableAnyAnyObject 完全不同。后两者是协议。前者是类型擦除结构。 stdlib 中的前缀 Any... 表示“类型橡皮擦”,除了奇怪的特殊情况(您应该尽可能避免)AnyAnyObject

【讨论】:

  • 我知道 AnyHashable 只是一个用于擦除类型的包装器,这就是我使用它的原因。但我猜这种不一致的行为让我失望了。我认为它有一些速记支持,可以忽略基本属性以便于使用,因为它适用于某些类型(以及除枚举之外的任何类型)。
猜你喜欢
  • 2013-03-17
  • 1970-01-01
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 2015-08-03
相关资源
最近更新 更多