Swift 中Range 和 NSRange的区别
NSRange
OC中的NSRange是一个结构体,表示一个区间,通常配合NSString字符串使用
typedef struct _NSRange {
NSUInteger location;
NSUInteger length;
} NSRange;
location
表示起始位置,length
表示长度
NSRange range = NSMakeRange(0, 100);
Range
相比NSRange,Range(区间)要复杂的多,区间代表两个值的区间,它由上边界和下边界进行定义。
通过..<创建不包含上边界的Range (左闭右开区间 [a...b) )
var range = 0..<10 //0 ~ 9 Range<Int>
通过 ... 创建包含上下边界的ClosedRange( 闭区间 [a...b])
var cRange = "A"..."Z" //A ~ z ClosedRange<Character>
Range<Bound>和ClosedRange<Bound>都是范型类型,Bound遵守Comparable协议
@frozen struct Range<Bound> where Bound : Comparable
@frozen struct ClosedRange<Bound> where Bound : Comparable
不能对普通Range和ClosedRange进行迭代
范围下界必须>= 范围上界
CountableRange
可数范围CountableRange和CountableClosedRange的范型Bound遵守Strideable(以整数为步长的协议) 这两种范围遵守Sequence协议可以被迭代,以及Sequence协议规定的操作
typealias CountableRange<Bound> = Range<Bound> where Bound : Strideable, Bound.Stride : SignedInteger
事实上CountableRange和CountableClosedRange是对原Range和ClosedRange的扩展,只要边界是整数就是可数的范围
var range = 0..<10 //Range
var cRange = 0...10 //ClosedRange
// 可迭代
for i in range{
print(i) // 0 1 2 3 4 5 6 7 8 9
}
//Sequence协议下的方法都适用
range.map { $0 }
//...
PartialRange
部分范围是Range的变型版本,缺省一侧边界
PartialRangeUpTo缺少上边界 ..<b
var pRangeUp = ..<10.0 //PartialRangeUpTo
PartialRangeThrough缺少上边界 ...b
var pRangeT = ...10.0 //PartialRangeThrough
PartialRangeFrom缺少下边界 a...
var pRangeF = 1.0... //PartialRangeFrom
CountablePartialRangeFrom<Int>可数 缺少下边界 a<Int> ...
var cPRangeF = 0... //CountablePartialRangeFrom
只有CountablePartialRangeFrom可迭代
RangeExpression协议提供了contains判断某个元素是否包含在区间,等效的~=
public protocol RangeExpression { /// The type for which the expression describes a range. associatedtype Bound: Comparable func relative<C: Collection>( to collection: C ) -> Range<Bound> where C.Index == Bound func contains(_ element: Bound) -> Bool}extension RangeExpression { @inlinable public static func ~= (pattern: Self, value: Bound) -> Bool { return pattern.contains(value) } }
检查某个元素在区间内 contains(:) 等效 ~=
// 存在某个元素range.contains(5) // true// 等效的是 ~=range ~= 5 // true
Range和ClosedRange相互转换
一般情况下,Range和ClosedRange不可以相互转换,所以遇到参数类型是Range函数,也不能传入ClosedRange,只有当Range或者ClosedRange可数的时候,可以通过系统提供的方法转换,或者手动转换。
var range = 0..<5
var crange = 0...5
//Range 转 ClosedRange
ClosedRange(range)//0...4
//ClosedRange 转 Range
Range(crange) // 0..<6
NSRange转Range
NSRange 转Range 返回 可选的Range
var ocRange:NSRange = NSMakeRange(0, 100)
var range = Range(ocRange) //Optional(Range(0..<100))
Range 转NSRange ,Range必须是整数边界
var range = 0..<10
var ocRange:NSRange = NSMakeRange(range.upperBound,range.count)
var ocRange1 = NSRange(range)
通常来说,纯swift中很少遇到NSRange 转Range的情况,但是iOS开发中的经常会遇到NSString和String相互转换,富文本NSMutableAttributeString的使用