如何获取 Swift 中给定字符范围的完整行范围?
How to get the full line range for a given character range in Swift?
Apple 有一个古老的例子,如何在给定特定字符范围的情况下获取整行的范围:
Counting Lines of Text
为了获得第一行的完整行范围,他们调用了下面的Objective-C函数:
[string lineRangeForRange:NSMakeRange(0, 0)]
我试图在 Swift 中实现相同的功能,但我无法实现它,因为方法签名已更改:
string.lineRange(for: NSRange(location: 0, length: 0))
引发编译器错误:
Argument type 'NSRange' (aka '_NSRange') does not conform to expected type 'RangeExpression'
RangeExpression
是一些我还没有完全理解的奇怪协议。但是,我认为 Range<Bound>
符合它,所以我尝试了以下操作:
let range = NSRange(location: 0, length: 0)
textView.string.lineRange(for: Range<Int>(range)!)
这次我又遇到了一个编译错误:
Generic parameter 'R' could not be inferred
我在 Range
和 RangeExpression
中都找不到任何通用参数 R
。
这是怎么回事,我怎样才能让它发挥作用?
lineRange(for:)
(本质上)期望 String.Index
的范围,而不是整数范围。这是一个简单的例子:
let string = "Line1\nLine2"
// Find the full range of the line containing the first "1":
if let range = string.range(of: "1") {
let lineRange = string.lineRange(for: range)
print(string[lineRange]) // Line1
}
实际参数是R : RangeExpression, R.Bound == String.Index
类型的泛型参数,这意味着你也可以像string.startIndex...
或[=18=一样传递部分范围 ].
的Swift版本
NSString *string;
unsigned numberOfLines, index, stringLength = [string length];
for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++)
index = NSMaxRange([string lineRangeForRange:NSMakeRange(index, 0)]);
会是
let string = "Line1\nLine2"
var index = string.startIndex
var numberOfLines = 0
while index != string.endIndex {
let range = string.lineRange(for: index..<index)
numberOfLines += 1
index = range.upperBound
}
print(numberOfLines)
此处index..<index
担任NSMakeRange(index, 0)
的角色。
如果目的只是计算(或枚举)总行数,那么另一种方法是使用
string.enumerateLines(invoking: { (line, _) in
// ...
})
相反(比较 How to split a string by new lines in Swift)。
Apple 有一个古老的例子,如何在给定特定字符范围的情况下获取整行的范围:
Counting Lines of Text
为了获得第一行的完整行范围,他们调用了下面的Objective-C函数:
[string lineRangeForRange:NSMakeRange(0, 0)]
我试图在 Swift 中实现相同的功能,但我无法实现它,因为方法签名已更改:
string.lineRange(for: NSRange(location: 0, length: 0))
引发编译器错误:
Argument type 'NSRange' (aka '_NSRange') does not conform to expected type 'RangeExpression'
RangeExpression
是一些我还没有完全理解的奇怪协议。但是,我认为 Range<Bound>
符合它,所以我尝试了以下操作:
let range = NSRange(location: 0, length: 0)
textView.string.lineRange(for: Range<Int>(range)!)
这次我又遇到了一个编译错误:
Generic parameter 'R' could not be inferred
我在 Range
和 RangeExpression
中都找不到任何通用参数 R
。
这是怎么回事,我怎样才能让它发挥作用?
lineRange(for:)
(本质上)期望 String.Index
的范围,而不是整数范围。这是一个简单的例子:
let string = "Line1\nLine2"
// Find the full range of the line containing the first "1":
if let range = string.range(of: "1") {
let lineRange = string.lineRange(for: range)
print(string[lineRange]) // Line1
}
实际参数是R : RangeExpression, R.Bound == String.Index
类型的泛型参数,这意味着你也可以像string.startIndex...
或[=18=一样传递部分范围 ].
NSString *string;
unsigned numberOfLines, index, stringLength = [string length];
for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++)
index = NSMaxRange([string lineRangeForRange:NSMakeRange(index, 0)]);
会是
let string = "Line1\nLine2"
var index = string.startIndex
var numberOfLines = 0
while index != string.endIndex {
let range = string.lineRange(for: index..<index)
numberOfLines += 1
index = range.upperBound
}
print(numberOfLines)
此处index..<index
担任NSMakeRange(index, 0)
的角色。
如果目的只是计算(或枚举)总行数,那么另一种方法是使用
string.enumerateLines(invoking: { (line, _) in
// ...
})
相反(比较 How to split a string by new lines in Swift)。