[0...2]
是一个包含一个元素的数组,它充其量是Range<Int>
从 0 到 2 的 a。您不能将其分配给包含Int
s 的切片。
x[0...2]
另一方面是(可能)一个切片,并且Sliceable
只定义一个get
下标,而不是一个setter。因此,即使类型更兼容——也就是说,如果你尝试过x[0...2] = 0...2
,它至少试图用x
类似大小的集合的值替换其中的范围——它仍然不起作用。
编辑:正如@rintaro 指出的那样,Array 确实支持范围的设置器下标 - 所以如果x
是一个范围你可以做x[0...2] = Slice(0...2)
- 但它必须是你分配的切片,所以我仍然会选择replaceRange
.
如果你的意思是你想用一些值替换条目 0 到 2,你想要的是replaceRange
,只要你的集合符合RangeReplaceableCollection
(例如,Array
这样做):
var x = [0,1,2,3,4,5]
var y = [200,300,400]
x.replaceRange(2..<5, with: y)
// x is now [0,1,200,300,400,5]
请注意,替换的范围y
不必相同大小,集合将根据需要扩展/收缩。
此外,y
不必是数组,它可以是任何类型的集合(但必须是集合,而不是序列)。所以上面的代码可以写成:
var x = [0,1,2,3,4,5]
var y = lazy(2...4).map { $0 * 100 }
x.replaceRange(2..<5, with: y)
编辑:因此,根据您的编辑,一次性将任意大小的数组原位归零,您可以执行以下操作:
var x = [1.0,2.0,0.0]
// range to replace is the whole array's range,
// Repeat just generates any given value n times
x.replaceRange(indices(x), with: Repeat(count: x.count, repeatedValue: 0.0))
如果您只想将子范围归零,请相应地调整范围(和替换条目的数量)。
给定您的示例Point
类,假设它由引擎盖下的数组支持,您可以通过以下方式实现此行为:
struct Point<T: FloatLiteralConvertible> {
private var _vals: [T]
init(dimensions: Int) {
_vals = Array(count: dimensions, repeatedValue: 0.0)
}
mutating func replaceRange
<C : CollectionType where C.Generator.Element == T>
(subRange: Range<Array<T>.Index>, with newElements: C) {
// just forwarding on the request - you could perhaps
// do some additional validation first to ensure dimensions
// aren't being altered...
_vals.replaceRange(subRange, with: newElements)
}
}
var x = Point<Double>(dimensions:3)
x.replaceRange(0...2, with: [1.1,2.2,3.3])