代码之家  ›  专栏  ›  技术社区  ›  Minding Patec

斯威夫特:如何解决下标歧义。命名下标?

  •  1
  • Minding Patec  · 技术社区  · 7 年前

    我实现了一个有序字典,它有两个下标。第一个是索引(总是类型 Int )二是变型钥匙 keyType .

    一切正常直到 键入式 是 int ,因为现在下标显然是不明确的。

    “subscript”的不明确用法

    所以为了解决歧义,我试着简单地添加一个名称标签 key: 对于这个值,就像正常函数参数有它们一样,但是这导致了 key: keyType 被视为我的参数类型,导致此错误:

    不能用类型为“(key:int)”的索引下标类型为“OrderedDictionary”的值

    错误信息对我来说非常清楚,但我不知道如何解决这种矛盾。现在我在用一个函数 insert(for:value:) .

    下面是OrderedDictionary类:

    import Foundation
    
    struct OrderedDictionary<keyType: Hashable, valueType>: Sequence {
        typealias Element = (keyType, valueType)
    
        let comparator: ((Element, Element) -> (Bool))?
        var keys = [keyType]()
        var values = [keyType:valueType]()
        var count: Int {
            get {
                return keys.count
            }
        }
    
        public struct Iterator: IteratorProtocol {
            let parent: OrderedDictionary
            var position: Int = 0
    
            init(parent: OrderedDictionary) {
                self.parent = parent
            }
    
            mutating func next() -> (keyType, valueType)? {
                if position == parent.keys.count {
                    return nil
                }
                let entry = parent.getEntry(at: position)
                position += 1
                return entry
            }
        }
    
        init() {
            comparator = nil
        }
    
        init(comparator:  ((Element, Element) -> (Bool))?) {
            self.comparator = comparator
        }
    
        subscript(index: Int) -> valueType? {
            get {
                return self.values[self.keys[index]]
            }
            set(newValue) {
                let key = self.keys[index]
                if newValue == nil {
                    self.keys.remove(at: index)
                    self.values.removeValue(forKey: key)
                } else {
                    self.values[key] = newValue
                }
            }
        }
    
        subscript(key: keyType) -> valueType? {
            get {
                return self.values[key]
            }
            set(newValue) {
                if newValue == nil {
                    for i in (0..<self.keys.count) {
                        if self.keys[i] == key {
                            self.keys.remove(at: i)
                            break
                        }
                    }
                    self.values.removeValue(forKey: key)
                } else {
                    insert(for: key, value: newValue!)
                }
            }
        }
    
        mutating func insert(for key: keyType, value: valueType) {
            let oldValue = self.values.updateValue(value, forKey: key)
            if oldValue == nil {
                if comparator != nil {
                    for i in (0..<self.keys.count) {
                        if comparator!((key, value), getEntry(at: i)) {
                            self.keys.insert(key, at: i)
                            return
                        }
                    }
                }
                //First key, largest key or insertion order
                self.keys.append(key)
            }
        }
    
        func getEntry(at index: Int) -> Element {
            let key = self.keys[index]
            return (key, self.values[key]!)
        }
    
        func makeIterator() -> OrderedDictionary<keyType, valueType>.Iterator {
            return Iterator(parent: self)
        }
    
        mutating func removeAll() {
            self.keys.removeAll()
            self.values.removeAll()
        }
    }
    

    下面是swift中的一些例子:

    //Note: Index type 'Int' same as key type 'Int'
    var dict = OrderedDictionary<Int, String>()
    
    // Ambiguous
    dict[0] = "Hello"
    
    // Named (not valid)
    dict[key: 10] = "World"
    
    // Workaround
    dict.insert(for: 20, value: "!")
    

    我该如何解决这个模棱两可的问题?这在斯威夫特有可能吗?

    1 回复  |  直到 7 年前
        1
  •  3
  •   matt    7 年前

    与swift中的所有其他函数不同,默认情况下下标参数名不会外部化。(我认为这种不一致是语言中的一个错误。)

    所以,你在哪里

    subscript(key:
    

    …你得说

    subscript(key key:
    

    …为了揭露 key 打电话者的标签。


    实际上,我觉得你想要的是三个下标:

    subscript(index: Int)
    subscript(key: keyType)
    subscript(key key: keyType)
    

    你可以这样说 钥匙 在调用中,只是以防万一,如果你不这样做,就会产生歧义。