Swift字典查找导致编译时错误

时间:2014-08-17 15:18:56

标签: arrays dictionary collections swift

我正在把我的脚趾浸入Swift,但遇到了一个让我有些困惑的问题。给定一个整数索引,我试图获取Dictionary的相应键并返回与之关联的值。

使用以下结构作为示例:

Class CustomClass {
    private var collection: [String: [SifterIssue]] = ["MyStringKey": [MyCustomCollectionClass]()]

    /* ... */
}

我试图像这样解决问题:

var keys = Array(self.collection.keys)
var key: String = keys[section] as String
return self.collection[key].count // error is flagged here

但是发现这会导致编译器错误,该错误表明'String'不能转换为'DictionaryIndex'。难倒,我尝试了一个稍微冗长的解决方案,并惊讶地发现这个编译和工作没有问题。

var keys = Array(self.collection.keys)
var key: String = keys[section] as String
var collection: [MyCustomCollectionClass] = self.collection[key]! as [MyCustomCollectionClass]
return issues.count

任何人都可以向我解释为什么第一个解决方案拒绝编译?

2 个答案:

答案 0 :(得分:2)

正如@Zaph所说,忽视潜在的致命错误是一个坏主意,而且这部分内容很快就是为了帮助而设计的。这是我能提出的最“敏捷”的代码:

func collectionCount(#section: Int) -> Int? {
    switch section {
    case 0..<collection.count: // Make sure section is within the bounds of collection's keys array
        let key = collection.keys.array[section] // Grab the key from the collection's keys array
        return collection[key]!.count // We can force unwrap collection[key] here because we know that key exists in collection
    default:
        return nil
    }
}

它使用swift的switch语句的范围/模式匹配功能来确保section collection数组范围内的keys;感觉比使用if更“狡猾”,主要是因为我找不到在Range语句中使用swift的if的方法。它还使用collection.keys懒惰属性array作为快捷方式,而不是使用Array创建新的Array(collection.keys)。由于我们已确保section位于collection.keys的范围内,因此我们可以在collection[key]!获取count时强行解包{。}}。

为了好玩,我还制作了一个通用函数,它将一个集合作为输入来概括:

func collectionCount<T,U>(#collection: [T:[U]], #section: Int) -> Int? {
    switch section {
    case 0..<collection.count: // Make sure section is within the bounds of collection's keys array
        let key = collection.keys.array[section] // Grab the key from the collection's keys array
        return collection[key]!.count // We can force unwrap collection[key] here because we know that key exists in collection
    default:
        return nil
    }
}

[T:[U]]基本上表示collection必须是Dictionary,其中T项的值为Array U

答案 1 :(得分:1)

忽略致命的潜在错误是一个非常糟糕的主意。 Optionals的全部原因是为了防止在运行时崩溃。

func collectionCount(#section: Int) -> Int? {
    var keys = Array(self.collection.keys)
    if section < keys.count {
    var key = keys[section] as String
        println("key: \(key)")
        return self.collection[key]!.count
    }
    else {
        // handle error here
        return nil
    }
}

投掷“!”在不知道值从不为零的情况下解包比使用nil的Objective-C处理更糟糕。如果这成为大量开发人员处理Optionals的标准方式,那么Swift将是一场灾难。请不要这样做。