Swift:如何解决下标歧义。命名下标?

Swift: How to resolve subscript ambiguity. Named subscripts?

我实现了一个有序字典,它有两个下标。第一个用于索引(始终为 Int 类型),第二个用于可变类型 keyType.

的键

keyTypeInt 之前一切正常,因为现在下标显然不明确。

Ambiguous use of 'subscript'

所以为了解决歧义,我尝试简单地为值添加一个名称标签 key:,就像普通函数参数一样,但这导致 key: keyType 被视为我的参数类型,导致此错误:

Cannot subscript a value of type 'OrderedDictionary' with an index of type '(key: Int)'

错误信息我已经很清楚了,但我不知道如何解决歧义。现在我正在使用函数 insert(for:value:).

这是 OrderedDictionary class:

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: "!")

如何解决这种歧义?这在 Swift 中甚至可能吗?

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

所以,你有

subscript(key:

...你需要说

subscript(key key:

...为了向调用者公开 key 标签。


其实我觉得你要的是三个下标:

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

这样你就可以在通话中说 key 以防万一你不这样做会导致歧义。