2017-06-26 51 views
1

我試圖擴展Array<MutatingCollection>,所以我可以鏡像數組的內容,但編譯器說我不能調用reverse()上的元素數組,儘管在MutatingCollection協議中定義了reverse()Array <MutableCollection>的Swift擴展將不允許reverse()

我想要做這樣的事情:

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 { 
     mutating func mirror() { 
      for index in self.indices { 
       self[index].reverse() 
      } 
     } 
    } 

我已經嘗試過作爲self.map {array in array.reverse()}以及(我認爲做同樣的事情,但我不完全grok map())兩種方式導致相同的錯誤消息:

Member 'reverse' cannot be used on value of type 'MutableCollection'

編輯:我可以直接調用相同的代碼,它按照我的意圖工作。

Playgrounds Screenshot

也許我使用extension不當,或斯威夫特遊樂場以某種方式阻礙了我的訪問。

回答

1

首先,擴展應聲明如下:

extension Array where Element : MutableCollection { 

你要檢查Element堅持協議MutableCollection,並不在於它是一個MutableCollection

但是,那麼我由於某種原因,無法撥打subscript上的reverse方法。我已經能夠做的最好的是這樣的:

extension Array where Element : MutableCollection { 
    mutating func mirror() { 
    for index in self.indices { 
     self[index] = self[index].reversed() as! Element 
    } 
    } 
} 

,因爲你需要它的工作,雖然強制轉換是很醜陋,我不喜歡這樣做哪些工作。我想我應該測試演員是肯定的,但我不能看到任何情況下調用reversed()會導致無法回到Element的集合。

編輯:

我想通了這個問題。 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其元素是合作,將MutableCollectionBidirectionalCollection - 如[Array<Int>]甚至[ArraySlice<Int>]

可以在斯威夫特看到完整的代碼reverse() 3。1這裏:

Reverse.swift

延伸MutableCollection其中自:BidirectionalCollection

+0

此崩潰如果'Element'是一個可變的集合,但不是一個數組,例如爲'var table = [[0,1,2] .dropFirst(),[3,4,5],[6,7,8]]',其中'Element'爲'ArraySlice '。 –

+0

@MartinR我相信我已經確定了在這個問題中提出的問題的原因,並且糾正了你提到的問題。請隨時檢查我的正確性。 – ColGraff

+1

通過額外的約束'Indices.Iterator.Element == Index',您可以擺脫人工的'guard let index = index ...',比較https://stackoverflow.com/a/44457590/1187415或https: //stackoverflow.com/a/40331858/1187415。在Swift 4中不應該有必要。 –