Разница между Kotlin и Java String split с регулярным выражением
если у нас есть val txt: kotlin.String = "1;2;3;" и как разбить его на массив чисел, то можете попробовать следующее:
val numbers = string.split(";".toRegex())
//gives: [1, 2, 3, ]
трейлинг-пустые String включается в результат CharSequence.split.
С другой стороны, если мы посмотрим на Java Strings, результат другой:
val numbers2 = (string as java.lang.String).split(";")
//gives: [1, 2, 3]
на этот раз, используя java.lang.String.split, результат не включает в себя трейлинг пустой String. Это поведение фактически предназначено, учитывая соответствующий JavaDoc:
этот метод работает так, как если бы вызывая метод разделения двух аргументов с заданным выражением и предельный аргумент нуля. конечные пустые строки не включаются в результирующий массив.
в версии Котлина, однако,0 также по умолчанию limit аргументов, документированных здесь, но внутренне Котлин карты 0 при отрицательном значении -1, когда java.util.regex.Pattern::split is под названием:
nativePattern.split(input, if (limit == 0) -1 else limit).asList()
кажется, что он работает по назначению, но мне интересно, почему язык, похоже, ограничивает API Java с предела 0 не предусмотрено.
1 ответов
реализация подразумевает, что это поведение java.lang.String.split достигнуто путем передачи limit = 0 это потеряно в Котлине. На самом деле, с моей точки зрения, он был удален для достижения согласованности между возможными вариантами в Котлине.
рассмотрим строку a:b:c:d: и :.
взгляните на то, что мы можем иметь на Java:
limit < 0 → [a, b, c, d, ] limit = 0 → [a, b, c, d] limit = 1 → [a:b:c:d:] limit = 2 → [a, b:c:d:] limit = 3 → [a, b, c:d:] limit = 4 → [a, b, c, d:] limit = 5 → [a, b, c, d, ] (идет так же, как с limit < 0) limit = 6 → [a, b, c, d, ]
...
получается, что limit = 0 опция несколько уникальна: она имеет трейлинг : ни заменить на новую, а с limit < 0 или limit >= 5, не сохраняется в последнем результирующем элементе (как с limit в 1..4).
мне кажется, что API Kotlin улучшает согласованность здесь: нет специального случая, который в некотором смысле теряет информацию о последнем разделителе, за которым следует пустая строка-она остается на месте либо как разделитель в последнем результирующем элементе, либо как конечная пустая запись.
IMO, функция Котлина, кажется, лучше подходит принцип наименьшего удивления. Нулевой предел в java.lang.String.split, напротив, больше похоже на специальное значение, изменяющее семантику метода. И отрицательные значения, что явно не поняли как ограничения и не совсем ясно, не копаясь в Javadoc.