鉴于结构Parameter
具有name
和value
属性,我想向数组添加一个下标,让我返回值 name 匹配下标参数的第一个找到的元素。
用法示例:
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 }
那么,为什么这个含糊不清?
这对我没有意义。
注意:所有其他候选项都是标准库中定义的struct 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
}
注意:
将数组约束到类类型并不能解决它:将发出相同的错误。