将String.Index转换为Int或将Range <String.Index>转换为NSRange

Har*_*ikk 11 string swift

所以,我发现与转换的情况下问题NSRangeRange<String.Index>,但我确实遇到相反的问题.

很简单,我有一个String和一个Range<String.Index>并且需要将后者转换成一个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)))
}
Run Code Online (Sandbox Code Playgroud)

这当然有效,但它不是很漂亮,我宁愿避免不得不抓住一个子串而只是以某种方式使用范围本身,这可能吗?

qwe*_*_so 10

如果你看一下你的定义,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
}
Run Code Online (Sandbox Code Playgroud)

所以实际上没有办法将它转换Int为有充分理由.根据字符串的编码,单个字符占用不同的字节数.唯一的方法是计算successor达到预期所需的操作次数String.Index.

编辑String已经改变了各种Swift版本的定义,但它基本上是相同的答案.要查看当前的定义,只需String在CMC中单击XCode中的定义即可到达根目录(也适用于其他类型).

distanceTo是一个扩展到各种协议.只需String在CMD点击后在源代码中查找它.


hnh*_*hnh 6

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

转换Range<String.Index>NSRange

let range   = s[s.startIndex..<s.endIndex]
let nsRange = NSRange(range, in: s)
Run Code Online (Sandbox Code Playgroud)

转换NSRangeRange<String.Index>

let nsRange = NSMakeRange(0, 4)
let range   = Range(nsRange, in: s)
Run Code Online (Sandbox Code Playgroud)

请记住,它NSRange是基于 UTF-16 的,而Range<String.Index>Character基于的。因此,您不能仅使用计数和位置在两者之间进行转换!


Ale*_*kov 5

let index: Int = string.startIndex.distanceTo(range.startIndex)
Run Code Online (Sandbox Code Playgroud)