Как получить полный диапазон строк для заданного диапазона символов в Swift? - PullRequest
0 голосов
/ 22 февраля 2019

У Apple есть старый пример того, как получить диапазон всей строки, учитывая определенный диапазон символов:

Подсчет строк текста

Чтобы получитьполный диапазон первой строки, они вызывают следующую 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

Я не смог найти ни одного общего параметра R, ни в Range, ни в RangeExpression.

Что все это значит и как я могу заставить его работать?

1 Ответ

0 голосов
/ 22 февраля 2019

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... или ..<string.endIndex.

Swift-версия образца кода Objective C

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
    // ...
})

вместо этого (сравните Какразбить строку по новым строкам в Swift ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...