在Swift 2中定义不可变字典数组的优雅方法是什么?

时间:2015-10-07 14:35:22

标签: arrays swift dictionary syntax

我想使用Swift 2可能使用的最干净,最易读的语法来定义静态字典数组。不幸的是,我不断收到Type of expression is ambiguous without more context错误。

例如:

    let items: [[MyEnum:AnyObject]] = [
        [ .EnumKey: 1, .AnotherKey: ["cat", "dog", "bird"] ],
        [ .EnumKey: 2, .AnotherKey: ["racoon"] ]
    ]

我做谷歌的答案,但找不到一个好的例子。有些人建议使用var并在每行添加一个值,但我觉得这很麻烦,因为我知道数组及其项目不会改变。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:2)

您看到的差异是由于您是否导入基础而产生的。

在您的示例中,您键入的词典为:

[MyEnum:AnyObject]

但是,您使用Ints和Arrays初始化它们。在严格的Swift世界中,Int和Array是结构体,不符合AnyObject。 AnyObject是一个只有类隐式符合的协议。但是,一旦你导入Foundation,那么东西就会被桥接到NSNumber,NSString,NSArray等。这些都是类,显然这会给编译器带来歧义。错误消息是正确的,但在您知道幕后发生的事情之前有点难以理解。

我建议将AnyObject更改为Any。

enum MyEnum {
     case EnumKey
     case AnotherKey
}

let items: [[MyEnum:Any]] = [
        [ .EnumKey: 1, .AnotherKey: ["cat", "dog", "bird"] ],
        [ .EnumKey: 2, .AnotherKey: ["racoon"] ]
    ]

这应该有效并且技术上更正确。

但是,如果你需要你的词典与NSDictionary联系,那么你将不得不采取另一种方式。在该实例中,您可以使用AnyObject,但您必须将值键入为NSNumber和NSArray。此外,我更改了您的枚举,以使用String原始值作为键。

enum MyEnum: String {
    case EnumKey
    case AnotherKey
}

let items: [[String:AnyObject]] = [
        [ MyEnum.EnumKey.rawValue: NSNumber(integer: 1), MyEnum.AnotherKey.rawValue: ["cat", "dog", "bird"] as NSArray ],
        [ MyEnum.EnumKey.rawValue: NSNumber(integer: 2), MyEnum.AnotherKey.rawValue: ["racoon"] as NSArray ]
    ]

有关AnyObject奇怪行为的更多信息,本博客提供了一些很好的信息: http://www.drewag.me/posts/swift-s-weird-handling-of-basic-value-types-and-anyobject