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

Min*_*ing 3 named-parameters swift

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

这一切都工作正常,直到keyTypeis Int,因为现在下标显然不明确。

“下标”的使用不明确

因此,为了解决歧义,我尝试简单地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()
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有一些 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: "!")
Run Code Online (Sandbox Code Playgroud)

我该如何解决这种歧义?这在 Swift 中可能吗?

mat*_*att 6

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

那么,你在哪里

subscript(key:
Run Code Online (Sandbox Code Playgroud)

...你需要说

subscript(key key:
Run Code Online (Sandbox Code Playgroud)

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


实际上,在我看来你想要的是三个下标:

subscript(index: Int)
subscript(key: keyType)
subscript(key key: keyType)
Run Code Online (Sandbox Code Playgroud)

这样,您就可以key在电话中说,以防万一您不说的话会导致歧义。