将String.Index转换为Int或Range<;字符串索引>;改变

将String.Index转换为Int或Range<;字符串索引>;改变,string,swift,String,Swift,因此,我发现了与将NSRange转换为Range相关的问题,但实际上我遇到了相反的问题 很简单,我有一个字符串和一个范围,需要将后者转换为NSRange,以便与旧函数一起使用 到目前为止,我唯一的解决方法是抓取一个子字符串,如下所示: func foo(theString: String, inRange: Range<String.Index>?) -> Bool { let theSubString = (nil == inRange) ? theString :

因此,我发现了与将
NSRange
转换为
Range
相关的问题,但实际上我遇到了相反的问题

很简单,我有一个
字符串
和一个
范围
,需要将后者转换为
NSRange
,以便与旧函数一起使用

到目前为止,我唯一的解决方法是抓取一个子字符串,如下所示:

func foo(theString: String, inRange: Range<String.Index>?) -> Bool {
    let theSubString = (nil == inRange) ? theString : theString.substringWithRange(inRange!)
    return olderFunction(theSubString, NSMakeRange(0, countElements(theSubString)))
}
func-foo(字符串:String,inRange:Range?)->Bool{
让substring=(nil==inRange)?the string:theString.substringWithRange(inRange!)
返回olderFunction(子字符串,NSMakerRange(0,countElements(子字符串)))
}

这当然是可行的,但它不是很漂亮,我更愿意避免抓取子字符串并以某种方式使用范围本身,这是可能的吗?

如果查看
string.Index
的定义,您会发现:

struct Index : BidirectionalIndexType, Comparable, Reflectable {

    /// Returns the next consecutive value after `self`.
    ///
    /// Requires: the next value is representable.
    func successor() -> String.Index

    /// Returns the previous consecutive value before `self`.
    ///
    /// Requires: the previous value is representable.
    func predecessor() -> String.Index

    /// Returns a mirror that reflects `self`.
    func getMirror() -> MirrorType
}
所以实际上没有办法把它转换成Int,这是有充分理由的。根据字符串的编码,单个字符占用的字节数不同。唯一的方法是计算需要多少后续操作才能达到所需的
String.Index

Edit不同的Swift版本中,
String
的定义发生了变化,但答案基本相同。要查看当前的定义,只需单击XCode中的
字符串
定义即可到达根目录(也适用于其他类型)


distanceTo
是一个扩展,适用于各种协议。只需在CMD单击后的
字符串
源代码中查找它。

您可以使用此函数,并在需要转换时调用它

let index: Int = string.startIndex.distanceTo(range.startIndex)
extension String
{ 
    func CnvIdxTooIntFnc(IdxPsgVal: Index) -> Int
    {
        return startIndex.distanceTo(IdxPsgVal)
    }
}

在Swift 4中,不推荐使用
distanceTo()
。您可能必须将
String
转换为
NSString
,以利用其
-[NSString rangeOfString:][/code>方法,该方法返回
NSRange

Swift 4完整解决方案:

OffsetIndexableCollection(使用Int索引的字符串)

让a=“01234”
打印(a[0])//0
打印(a[0…4])//01234
打印(a[…])//01234
打印(a[…“1”}){
打印(编号)//2
}

我不知道是哪个版本引入了它,但在Swift 4.2中,您可以轻松地在两者之间进行转换

要将
范围
转换为
NSRange

let range   = s[s.startIndex..<s.endIndex]
let nsRange = NSRange(range, in: s)
请记住,
NSRange
基于UTF-16,而
Range
基于
字符。

因此,您不能仅使用计数和位置在两者之间进行转换!

您想在哪里使用范围而不是子字符串?作为olderFunction的参数?那么它的用途是什么?我想我的示例可能会混淆这个问题,因为它只返回
Bool
,但是,其他一些类似的函数返回更复杂的结果s、 在使用此子字符串技巧时需要更正,因为它们返回的索引将用于
子字符串而不是
字符串
。是否真的没有办法将
字符串.Index
转换为
Int
?对我有效的东西(在我的情况下):
如果idx.startIndex==url.startIndex{//some code}
我理解它的原因,但不幸的是,如果我至少能确定这两个字符串,那就不会太糟糕了。索引值表示5个字符的差异,就像我可以使用advance(5)一样为了简单地更正我的结果,因为这会使使用旧代码变得非常棘手=(您可以使用扩展名将其缩写。字符串实际上是伏都教或黑魔法。我们永远不应该离开7位ASCII树;-)也许不是,但实际上我刚刚发现了
distance()
函数(或者预处理器,我不确定);不管怎样,它允许确定两个
字符串之间的差异。Index
是这样的:
距离(theString.startIndex,theRange.startIndex)
。它仍然不漂亮,但我想我现在可以让它工作,我只是希望它将来不必处理巨大的字符串;)幸运的是,大多数字符串都相对较短。但是,我看到过将BLOB作为字符串处理的实现(这当然不是一个好主意)。另请参见此处:这列出了所有预定义函数。这只是一个设计错误,因为您必须了解所有这些函数,而我忘记了这一点:-(是的,NSString比一般的String更方便。我很感激你的回答!
let range   = s[s.startIndex..<s.endIndex]
let nsRange = NSRange(range, in: s)
let nsRange = NSMakeRange(0, 4)
let range   = Range(nsRange, in: s)