Swift

Swift 中Range 和 NSRange的区别

2021-11-04  本文已影响0人  你duck不必呀

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的使用

上一篇下一篇

猜你喜欢

热点阅读