Разница между Kotlin и Java String split с регулярным выражением
если у нас есть val txt: kotlin.String = "1;2;3;"
и как разбить его на массив чисел, то можете попробовать следующее:
val numbers = string.split(";".toRegex())
//gives: [1, 2, 3, ]
трейлинг-пустые String
включается в результат CharSequence.split
.
С другой стороны, если мы посмотрим на Java String
s, результат другой:
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.