0

这是 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 中试过这个。

4

1 回答 1

2

AnyHashable explicitly type-erases:

The AnyHashable type forwards equality comparisons and hashing operations to an underlying hashable value, hiding its specific underlying type.

The fact that this happens to work for some types is the surprising fact, not that it fails for enums. I would expect it's a performance optimization to help with dictionaries. But this isn't how you're expected to use AnyHashable. The expected usage is to initialize it with AnyHashable.init, not as AnyHashable.

What you meant is this:

enum TestEnum: String {
    case test
}

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

Note that AnyHashable is a completely different kind of thing than Any or AnyObject. The latter two are protocols. The former is a type-erasing struct. The prefix Any... in the stdlib means "type-eraser" except for the oddball special-cases (that you should avoid as much as humanly possible) Any and AnyObject.

于 2017-09-26T22:47:47.140 回答