美文网首页Swift
Swift 中Range 和 NSRange的区别

Swift 中Range 和 NSRange的区别

作者: 你duck不必呀 | 来源:发表于2021-11-04 10:49 被阅读0次

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

    相关文章

      网友评论

        本文标题:Swift 中Range 和 NSRange的区别

        本文链接:https://www.haomeiwen.com/subject/npohzltx.html