Arrays 数组的快速扩展<;可变集合>;韩元';不允许反向

Arrays 数组的快速扩展<;可变集合>;韩元';不允许反向,arrays,swift,extension-methods,swift-playground,Arrays,Swift,Extension Methods,Swift Playground,我试图扩展Array,以便镜像数组数组的内容,但编译器说我无法对数组中的元素调用reverse(),尽管reverse()在MutatingCollection协议中定义 我想这样做: var table = [[0,1,2], [3,4,5], [6,7,8]] table.mirror() //table now [[2,1,0], // [5,4,3], // [8,7,6]] extension

我试图扩展
Array
,以便镜像数组数组的内容,但编译器说我无法对数组中的元素调用
reverse()
,尽管
reverse()
MutatingCollection
协议中定义

我想这样做:

var table = [[0,1,2],
             [3,4,5],
             [6,7,8]]
table.mirror()
//table now [[2,1,0],
//           [5,4,3],
//           [8,7,6]]
extension Array where Element : MutableCollection {
以下是我的(不工作)代码:

我也尝试过将其作为
self.map{array in array.reverse()}
(我认为它做了同样的事情,但我没有完全摸索
map()
),这两种方法都会导致相同的错误消息:

成员“reverse”不能用于“MutableCollection”类型的值。

编辑:我可以直接调用相同的代码,它可以按照我的预期工作


可能我使用的
扩展名不正确,或者Swift Playgrounds以某种方式阻止了我的访问。

首先,扩展名应该声明如下:

var table = [[0,1,2],
             [3,4,5],
             [6,7,8]]
table.mirror()
//table now [[2,1,0],
//           [5,4,3],
//           [8,7,6]]
extension Array where Element : MutableCollection {
您希望检查
元素是否符合协议
MutableCollection
,而不是它是否是
MutableCollection

但是,由于某种原因,我无法调用
下标上的
reverse
方法。我能做的最好的事情是:

extension Array where Element : MutableCollection {
  mutating func mirror() {
    for index in self.indices {
      self[index] = self[index].reversed() as! Element
    }
  }
}
虽然强制演员阵容很难看,我也不喜欢这样做,但这是你需要的。我想我应该测试强制转换以确定是否正确,但我看不到调用
reversed()
会导致无法将集合强制转换回
元素

编辑:

我解决了这个问题。
reverse()
方法仅在
MutableCollection
同时也是
BidirectionalCollection
时有效。此代码现在可以正常工作:

extension MutableCollection where
  Iterator.Element : MutableCollection &
                     BidirectionalCollection,
  Indices.Iterator.Element == Index {
  mutating func mirror() {
    for index in self.indices {
      self[index].reverse()
    }
  }
}
现在,代码应该适用于所有
MutableCollection
,它们的元素都是
MutableCollection
BidirectionalCollection
——例如
[Array]
甚至
[ArraySlice]

您可以在Swift 3.1中看到
reverse()
的完整代码:

扩展可变集合,其中Self:BidirectionalCollection


如果
Element
是可变集合而不是数组,则会崩溃,例如,对于
var table=[[0,1,2].dropFirst(),[3,4,5],[6,7,8]
,其中
Element
ArraySlice
@MartinR我相信我已经确定了这个问题的原因,并纠正了您提到的问题。请随时为我检查它的正确性。通过附加约束
Index.Iterator.Element==Index
,您可以摆脱人为的
guard let Index=Index…
,比较或。它在Swift 4中不应该是必需的。@MartinR Perfect!我一直在寻找实现这一目标的最佳途径。谢谢,谢谢你们两个!