&#39;字符串&#39;不能转换为&#39; DictionaryIndex <string,[(string)]?=“”>&#39;编译错误,非常基本的字典用法</string,>

时间:2014-11-29 23:53:06

标签: swift

我正在尝试创建一个非常简单的字典,将字符串映射到Swift中的字符串数组。代码如下所示:

class FirstViewController: UIViewController {

    var characters:[String] = []
    var adjacency = [String : [String]?]()

    override func viewDidLoad() {
        super.viewDidLoad()

        characters = loadCharacters()
        adjacency = loadAdjacency()

        var character:String = characters[0]
        var adj:[String] = adjacency[character] // This line gives the first compiler error
        adj = adjacency["a"] // This line gives the second compiler error

        println(adj)
    }

    func loadCharacters() -> [String] {
        return ["a", "b", "c"]
    }

    func loadAdjacency() -> [String : [String]?] {
        return ["a": ["a", "b", "c"], "b": ["b", "c", "d"], "c": ["c", "d", "e"]]
    }
}

第一个编译器错误是:     'String' is not convertible to 'DictionaryIndex<String, [(String)]?>'

第二个编译器错误是:     '(String, [(String)]?)' is not convertible to '[String]'

据我所知,这两行都应该是等效和正确的 - 我从字典查找中使用字符串作为键来获取字符串数组。我哪里错了?

如果我按如下方式编写,代码将编译并正确运行:

class SecondViewController: UIViewController {

    var keyArray:[String] = []
    var dict = [String : [String]?]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        keyArray = ["a", "b", "c"]
        dict = ["a": ["a", "b", "c"], "b": ["b", "c", "d"], "c": ["c", "d", "e"]]

        println(dict[keyArray[1]])

    }

}

顺便说一下,我使用的是Xcode Version 6.1(6A1052d),而我正在运行OSX 10.9.4。我即将升级到优胜美地,以防万一我的设置发生了一些奇怪的事情,但我想我只是遗漏了一些明显的东西。

2 个答案:

答案 0 :(得分:5)

错误信息在这里不是很有帮助,它根本不涉及实际问题......

解决方案1:

var adj/*:[String]??*/ = adjacency[character] // adj is Optional<Optional<[String]>>
adj = adjacency["a"]
println(adj) // Optional(Optional(["a", "b", "c"]))

解决方案2:

var adj/*:[String]*/ = adjacency[character]!! // adj is [String]
adj = adjacency["a"]!!
println(adj) // [a, b, c]

解决方案3 - 安全的方式:

if let adj = adjacency[character] { // adj is Optional<String[]>
    if let adj2 = adj {  // adj2 is String[]
        println(adj2)
    }
}

答案 1 :(得分:3)

The Swift Programming Guide州:

  

Swift的Dictionary类型将其键值下标实现为   接受和接收可选类型的下标。 [...]字典类型   使用可选的下标类型来模拟不是每个键的事实   将有一个值,并提供一种方法来删除键的值   为该密钥分配一个零值。

例如,在以下使用Type Inference的代码中,myString是可选的,并且是nil

let myDict = ["A" : "Alabama", "D" : "Delaware", "M" : "Montana"]
let myString = myDict["Z"] //dictionary subscripts return optionals (here, it's String?)

您可以在myString上使用针对所选项目的快速帮助来检查它是否真的是可选的(选项⌥ +点击或控制^ + 命令⌘ + )。

返回您的代码:

var adj:[String] = adjacency[character]

上一行无法编译,因为adjacency[character]会返回一个可选项(可能是nil),但同时您希望adj成为非可选项永远不会[String]的{​​{1}}。

为了解决这个问题,您可以像这样重写代码:

nil