首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MutableCollection对RangeReplaceableCollection

MutableCollection对RangeReplaceableCollection
EN

Stack Overflow用户
提问于 2016-06-25 22:29:27
回答 1查看 698关注 0票数 6

来自API参考

MutableCollection协议允许更改集合元素的值,但不允许更改集合本身的长度。有关需要添加或删除元素的操作,请参阅RangeReplaceableCollection协议。

但是,MutableCollection需要以下下标:

代码语言:javascript
复制
subscript(bounds: Range<Self.Index>) -> Self.SubSequence { get set }

这不允许更改集合的长度吗?例如,我们不能称这个下标设置器为空范围和非空子序列吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-25 23:25:47

简短回答:

如果您有一个MutableCollection类型的变量,那么您必须调用下标setter,它只有一个范围和一个长度相同的新片。某些符合MutableCollection的类型(如Array)允许使用不同长度的替换来插入或删除元素,但一般而言,可变集合不需要这样做。

特别是,如果范围和新的切片不具有相同的长度,则MutableCollection下标设置器的默认实现将中止运行时异常。

更长的答案:

首先请注意,您不必实现

代码语言:javascript
复制
public subscript(bounds: Range<Index>) -> MutableSlice<Self>

在您自己的集合中,因为它在协议扩展中具有默认实现。从该方法的源代码中可以看到,下标集调用

代码语言:javascript
复制
internal func _writeBackMutableSlice()

函数,它实现了这里。该函数首先将元素的公共数量从切片复制到目标范围,然后验证下标范围和新的切片是否具有相同的长度:

代码语言:javascript
复制
_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")

因此,您不能通过(默认)下标设置器更改MutableCollection的长度,并且尝试这样做将中止程序。

作为一个例子,让我们定义一个符合MutableCollection的“最小”类型

代码语言:javascript
复制
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
        }
    }
}

然后,将集合的一部分替换为相同长度的片,工作如下:

代码语言:javascript
复制
var mc = MyCollection([0, 1, 2, 3, 4, 5])
mc[1 ... 2] = mc[3 ... 4]
print(mc) // [0, 3, 4, 3, 4, 5]

但是对于不同的长度,它会在运行时异常下中止:

代码语言:javascript
复制
mc[1 ... 2] = mc[3 ... 3]
// fatal error: Cannot replace a slice of a MutableCollection with a slice of a smaller size

请注意,符合MutableCollection的具体类型可能允许在下标设置器中替换不同的长度,例如Array

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38033512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档