Добавление нижнего индекса в ограниченный массив

Учитывая структуру Parameter который имеет name и value свойство, я хотел бы добавить Subscript в массив, который позволяет мне возвращать значение первого найденного элемента, имя которого соответствует параметру subscript.

Пример использования:

let params = [Parameter("firstName", "John"), Parameter("lastName", "Doh")]    
let value = params["firstName"] // returns "John"

Редактировать: ошибка компилятора возникает, только если я определил массив следующим образом:

let params: [ParameterType] = [Parameter("firstName", "John"), Parameter("lastName", "Doh")]    
let value = params["firstName"] // returns "John"

Теперь, когда я это реализую, я получаю ошибку компилятора:

error: ambiguous reference to member 'subscript'
        let value = params["firstName"] // returns "John"
                    ^~~~~~

note: found this candidate
    public subscript (index: Int) -> Element { get set }

note: found this candidate
    public subscript (name: String) -> String? { get set }

note: found this candidate
    public subscript (bounds: Range<Self.Index>) -> MutableSlice<Self> { get set }

note: found this candidate
    public subscript (position: Self.Index) -> Self.Base.Generator.Element { get }

Итак, почему это неоднозначно?

Это не имеет смысла для меня.

Примечание: все остальные кандидаты являются реализациями для структуры Array, определенного в стандартной библиотеке.

Например, как это

subscript (index: Int) -> Element а также

subscript (name: String) -> String?

неоднозначный?

Я подозреваю, что сообщения об ошибках просто сбивают с толку, и настоящая ошибка заключается в том, что параметр типа Element не полностью указан. Во всяком случае, как это могло быть реализовано?


Это моя попытка реализовать это.

Мне известно, что - из-за текущих ограничений в языке - реализация нижнего индекса фактически определена для набора типов элементов, соответствующих ParameterType:

public protocol ParameterType {
    init(_ name: String, _ value: String)
    var name: String { get }
    var value: String { get }
}

public extension Array where Element: ParameterType {

    subscript(name: String) -> String? {
        get {
            let a = self.filter { $0.name == name }
            if let e = a.first {
                return e.value
            } else {
                return nil
            }
        }
        set(newValue) {
            let i = self.index { $0.name == name }
            if let index = i {
                if let value = newValue {
                    self[index] = Element(name, value)
                } else {
                    self.remove(at:index)
                }
            } else {
                if let value = newValue {
                    let param = Element(name, value)
                    self.append(param)
                } else { /* */ }
            }
        }
    }

}

А вот один конкретный тип, соответствующий ParameterType:

public struct Parameter: ParameterType {
    public init(_ name: String, _ value: String) {
        self.name = name
        self.value = value
    }
    public var name: String
    public var value: String
}

Замечания:

Ограничение массива типом класса не решает проблему: будут выдаваться те же ошибки.

0 ответов

Другие вопросы по тегам