Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 为特定类型的集合添加协议一致性_Swift - Fatal编程技术网

Swift 为特定类型的集合添加协议一致性

Swift 为特定类型的集合添加协议一致性,swift,Swift,当元素是特定类型时,我想将协议一致性添加到集合 作为我试图做的一个例子,考虑下面的(设计的)代码,将数值绑定到表达式中的占位符。 typealias占位符=字符串 枚举数{ 大小写整数(Int64) 箱子浮动(双) } 协议绑定{ func绑定(到表达式:表达式,用于占位符:占位符) } 类表达式{ 变量值:[占位符:数字]=[:] } 扩展名Int:Bindable{ func绑定(到表达式:表达式,用于占位符:占位符){ 表达式.values[占位符]=.integer(Int64(self

元素
是特定类型时,我想将协议一致性添加到
集合

作为我试图做的一个例子,考虑下面的(设计的)代码,将数值绑定到表达式中的占位符。

typealias占位符=字符串
枚举数{
大小写整数(Int64)
箱子浮动(双)
}
协议绑定{
func绑定(到表达式:表达式,用于占位符:占位符)
}
类表达式{
变量值:[占位符:数字]=[:]
}
扩展名Int:Bindable{
func绑定(到表达式:表达式,用于占位符:占位符){
表达式.values[占位符]=.integer(Int64(self))
}
}
扩展浮动:可绑定{
func绑定(到表达式:表达式,用于占位符:占位符){
表达式.values[占位符]=.float(双精度(自))
}
}
类生成器{
let expression=expression()
func集(u值:T,用于占位符:占位符){
bind(to:expression,for:placeholder)
}
}
使用此代码可以设置
Int
Float
值:

let builder=builder()
builder.set(Int(10),表示“Int”)
生成器设置(浮动(10),表示“浮动”)
现在,当
元素
Int
时,我希望能够使用现有的
集合(:for:)
绑定数组的和:

扩展可绑定,其中Self:Collection,Element==Int{
func绑定(到表达式:表达式,用于占位符:占位符){
expression.values[placeholder]=.integer(Int64(self.reduce(0,+))
}
}
//错误:实例方法“set(\:for:)”要求“[Int]”符合“Bindable”
生成器集合([1,2],表示“总和”)
我错误地认为扩展将使
[Int]
符合
可绑定的要求

我可以通过向
Builder
添加一个额外的
集合(:for:)
函数来解决这个问题:

类生成器{
func集(值:T,用于占位符:占位符),其中T.Element==Int{
bind(to:expression,for:placeholder)
}
}
元素==Int的扩展集合{
func绑定(到表达式:表达式,用于占位符:占位符){
expression.values[placeholder]=.integer(Int64(self.reduce(0,+))
}
}
生成器集合([1,2],表示“总和”)

但是我想理解为什么第一种方法不起作用。

您认为这会使所有
[Int]
都符合
可绑定的

extension Bindable where Self: Collection, Element == Int {
上述事实说明:

将此
bind
方法添加到
Bindable
的所有符合项,该符合项也是
Int
的集合

你扩展了错误的东西。您应该在
[Int]
上编写扩展,而不是
Bindable
的符合项。你想说:

将此
bind
方法添加到
Int
的所有集合中(并使其符合
Bindable

上面的代码实际上不起作用。。。因为不幸的是,您无法通过扩展使一个协议与另一个协议保持一致,所以下一个选择是对阵列执行此操作:

extension Array : Bindable where Element == Int {
    func bind(to expression: Expression, for placeholder: Placeholder) {
        expression.values[placeholder] = .integer(Int64(self.reduce(0, +)))
    }
}

如果确实希望
set
接受通用集合/序列,可以为接受
序列的
set
添加另一个重载:

func set<S, T>(_ values: S,
               for placeholder: Placeholder,
               withIdentity identity: T,
               andReductionFunction reductionFunction: (T, S.Element) -> T)
    where S: Sequence, S.Element: Bindable, T: Bindable {
    values.reduce(identity, reductionFunction).bind(to: expression, for: placeholder)
}

您认为这使所有的
[Int]
都符合
可绑定的要求:

extension Bindable where Self: Collection, Element == Int {
上述事实说明:

将此
bind
方法添加到
Bindable
的所有符合项,该符合项也是
Int
的集合

你扩展了错误的东西。您应该在
[Int]
上编写扩展,而不是
Bindable
的符合项。你想说:

将此
bind
方法添加到
Int
的所有集合中(并使其符合
Bindable

上面的代码实际上不起作用。。。因为不幸的是,您无法通过扩展使一个协议与另一个协议保持一致,所以下一个选择是对阵列执行此操作:

extension Array : Bindable where Element == Int {
    func bind(to expression: Expression, for placeholder: Placeholder) {
        expression.values[placeholder] = .integer(Int64(self.reduce(0, +)))
    }
}

如果确实希望
set
接受通用集合/序列,可以为接受
序列的
set
添加另一个重载:

func set<S, T>(_ values: S,
               for placeholder: Placeholder,
               withIdentity identity: T,
               andReductionFunction reductionFunction: (T, S.Element) -> T)
    where S: Sequence, S.Element: Bindable, T: Bindable {
    values.reduce(identity, reductionFunction).bind(to: expression, for: placeholder)
}

谢谢你的回答。我尝试了你最初提到的第一种方法,但显然不起作用。看来真正的答案是,至少现在不能这样做。也许在未来的Swift版本中@sbooth如果您只想
set
能够接受
Collection
s,您可以添加另一个重载。请参阅编辑。中提到了这一点,Swift团队似乎认为这会带来比解决问题更多的问题。感谢您的回答。我尝试了你最初提到的第一种方法,但显然不起作用。看来真正的答案是,至少现在不能这样做。也许在未来的Swift版本中@sbooth如果您只想
set
能够接受
Collection
s,您可以添加另一个重载。见编辑。在中提到了这一点,似乎Swift团队认为这会带来比解决问题更多的问题。