Kotlin和Java String之间的区别与Regex分开

时间:2018-02-09 01:13:25

标签: java regex string kotlin

如果我们有val txt: kotlin.String = "1;2;3;"并希望将其拆分为数字数组,我们可以尝试以下方法:

val numbers = string.split(";".toRegex())
//gives: [1, 2, 3, ]

结尾的空String包含在CharSequence.split的结果中。

另一方面,如果我们查看Java String,结果会有所不同:

val numbers2 = (string as java.lang.String).split(";")
//gives: [1, 2, 3]

这一次,使用java.lang.String.split,结果不包括尾随空String。实际上,这种行为是在给定相应的JavaDoc:

的情况下实现的
  

此方法的作用就像通过使用给定表达式和 limit参数为零调用双参数split方法一样。 因此,结果数组中不包含尾随空字符串

在Kotlin的版本中,0也是默认的limit参数,记录为here,但内部Kotlin将0映射为负值-1java.util.regex.Pattern::splitcalled时:

nativePattern.split(input, if (limit == 0) -1 else limit).asList()

它似乎按预期工作但我想知道为什么该语言似乎限制了Java API,因为不再提供0的限制。

1 个答案:

答案 0 :(得分:11)

实现意味着通过传递在Kotlin中丢失的java.lang.String.split来实现limit = 0的行为。实际上,从我的观点来看,它被删除以实现Kotlin中可能的选项之间的一致性。

考虑字符串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 < 0limit >= 5替换,也不会保留在最后得到的项目(与1..4中的limit一样。)

在我看来,Kotlin API在这里提高了一致性:在某种意义上,没有特殊情况会丢失关于最后一个分隔符后跟一个空字符串的信息 - 它作为最后一个分隔符留在原地结果项目或作为尾随空条目。

IMO,Kotlin函数似乎更适合principle of least astonishment。相反,java.lang.String.split中的零限制看起来更像是修改方法语义的特殊值。负值也是如此,显然没有直观意义上的限制,如果不挖掘Javadoc就不太清楚。