relative(to:) 函数实际上做了什么?

What Does The relative(to:) Function Actually Do?

这是来自Swift Standard Library Documentation:

relative(to:)

Returns the range of indices within the given collection described by this range expression.

方法签名如下:

func relative<C>(to collection: C) -> Range<Self.Bound> where C : _Indexable, Self.Bound == C.Index

及其解释:

Parameters

collection

The collection to evaluate this range expression in relation to.

Return Value

A range suitable for slicing collection. The returned range is not guaranteed to be inside the bounds of collection. Callers should apply the same preconditions to the return value as they would to a range provided directly by the user.

最后,这是我的测试代码:

let continuousCollection = Array(0..<10)
var range = 0..<5
print(range.relative(to: continuousCollection))
//0..<5
range = 5..<15
print(range.relative(to: continuousCollection))
//5..<15
range = 11..<15
print(range.relative(to: continuousCollection))
//11..<15
let disparateCollection = [1, 4, 6, 7, 10, 12, 13, 16, 18, 19, 22]
range = 0..<5
print(range.relative(to: disparateCollection))
//0..<5
range = 5..<15
print(range.relative(to: disparateCollection))
//5..<15
range = 11..<15
print(range.relative(to: disparateCollection))
//11..<15

在每种情况下,relative(to:) 只是 returns 原始范围。这个方法应该做什么?

relative(to:) is a requirement of the RangeExpression 协议,Swift 的范围类型符合 Swift 4.

这包括:

如文档所述,在具有给定 Collection 的范围表达式上调用 relative(to:)(其中范围具有与集合的 Index 类型匹配的边界)returns 一个 Range 适合切片那个集合。

在半开范围的情况下,边界保持不变,如您所观察到的那样。但是,结果将与其他范围类型不同。例如,对于封闭范围,上限将需要增加(因为它不再包含在内)。对于部分范围,缺失的下限或上限需要分别为集合的 startIndexendIndex "filled in"。

例如:

let continuousCollection = Array(0 ..< 10)

do {
    let range = 0 ..< 5 // CountableRange
    print(range.relative(to: continuousCollection)) // 0..<5
}

do {
    let range = 0 ... 5 // ClosedCountableRange
    print(range.relative(to: continuousCollection)) // 0..<6
}

do {
    let range = 4... // CountablePartialRangeFrom
    print(range.relative(to: continuousCollection)) // 4..<10
}

do {
    let range = ..<9 // PartialRangeUpTo
    print(range.relative(to: continuousCollection)) // 0..<9
}

do {
    let range = ...3 // PartialRangeThrough
    print(range.relative(to: continuousCollection)) // 0..<4
}

RangeExpressionrelative(to:) 要求允许标准库编写 a generic ranged subscript on Collection,允许任意集合以任意范围类型作为下标 Index 界限:

let continuousCollection = Array(0 ..< 10)

print(continuousCollection[0 ..< 5]) // [0, 1, 2, 3, 4]
print(continuousCollection[0 ... 5]) // [0, 1, 2, 3, 4, 5]
print(continuousCollection[4...]) // [4, 5, 6, 7, 8, 9]
print(continuousCollection[..<9]) // [0, 1, 2, 3, 4, 5, 6, 7, 8]
print(continuousCollection[...3]) // [0, 1, 2, 3]