Short answer:
If you have a variable MutableCollection type, then you should call the index installer with only a range and a new slice that has the same length. Some types corresponding to a MutableCollection (for example, Array ) allow you to replace a different length for inserting or deleting elements, but in general, a mutable collection should not allow this.
In particular, the standard implementation of the MutableCollection setster setter is interrupted using a runtime exception if the range and the new slice do not have the same length.
Longer answer:
First of all, note that you do not need to perform
public subscript(bounds: Range<Index>) -> MutableSlice<Self>
in your own collection, since it has a default implementation in the protocol extension. As you can see from the source code for this method, the index setup tool calls
internal func _writeBackMutableSlice()
which is implemented here . This function first copies the total number of elements from slice to the target range, and then checks that the index range and the new slice are the same length:
_precondition( selfElementIndex == selfElementsEndIndex, "Cannot replace a slice of a MutableCollection with a slice of a smaller size") _precondition( newElementIndex == newElementsEndIndex, "Cannot replace a slice of a MutableCollection with a slice of a larger size")
Thus, you cannot change the length of the MutableCollection through (by default), and attempting to do this will result in the program being canceled.
As an example, let's use the definition of a "minimum" type corresponding to a MutableCollection :
struct MyCollection : MutableCollection, CustomStringConvertible { var storage: [Int] = [] init(_ elements: [Int]) { self.storage = elements } var description: String { return storage.description } var startIndex : Int { return 0 } var endIndex : Int { return storage.count } func index(after i: Int) -> Int { return i + 1 } subscript(position : Int) -> Int { get { return storage[position] } set(newElement) { storage[position] = newElement } } }
Then we replace part of the collection with a slice of the same length of work:
var mc = MyCollection([0, 1, 2, 3, 4, 5]) mc[1 ... 2] = mc[3 ... 4] print(mc)
But for different lengths, it is interrupted using a runtime exception:
mc[1 ... 2] = mc[3 ... 3]
Note that specific types corresponding to a MutableCollection may allow the replacement of different sides in their index installer, such as Array .