【问题标题】:Kotlin: is there a class for substrings?Kotlin:有子字符串的类吗?
【发布时间】:2020-06-23 02:34:18
【问题描述】:

有一个将字符串作为输入的递归函数。它将这个字符串分成几部分,并为每一部分调用自己。此函数不会更改输入字符串,只会读取它。该功能在 Kotlin 中实现。 要创建子字符串,调用子字符串函数:

    myFunc(str.substring(begin, length))

对此实施的有效性存在疑问。每次调用都会创建一个新字符串,尽管传递原始字符串中子字符串的开头和长度就足够了。 Kotlin 有子字符串类吗?例如,在 C++ 标准库中有一个类std :: string_view,而在Qt 中有一个类QStringRef。 Kotlin 中是否有类似的东西?

或者可能String类已经优化,子字符串函数没有分配新内存,而新实例使用与原来相同的内存缓冲区?

【问题讨论】:

  • 您可能正在寻找一种更像绳索而不是字符串的数据结构。绳索是由多个字符串或字符串视图构成的 CharSequence。插入和删除被建模为视图,而不是修改。这里有一个开源实现:ahmadsoft.org/ropes

标签: string kotlin substring


【解决方案1】:

您可以自己查看源代码进行检查。

对于 java.lang.String(由 Kotlin/JVM 使用),在 Java 7 之前它相当简单:String 具有对字符数组的引用,以及开始和结束索引。因此,虽然子字符串必须是新的 String 实例,但它具有对与生成它的 String 相同的字符数组的引用。换句话说,它优化了子字符串大小写。

不过,String 类现在更加复杂,而且现在似乎针对堆使用进行了更多优化:请参阅 this question

如果您真的关心这个特定方法的性能,您可以完全放弃创建对象,并传入原始字符串以及您自己的开始和结束值。但是,关于优化的常规规则适用:只有在热点中时才值得像这样使代码复杂化——并且您需要进行一些测试以证明它是否存在,以及您的重写是否真的改善了事情。

【讨论】:

    【解决方案2】:

    如果标准库函数中没有任何方法,可以创建Extention函数提供更丰富的支持。

    示例:删除字符串的第一个和最后一个字符

    fun String.removeFirstLastChar(): String =  this.substring(1, this.length - 1)
    
    fun main(args: Array<String>) {
        val myString= "Hello Everyone"
        val result = myString.removeFirstLastChar()
        println("First character is: $result")
    }
    When y
    

    你运行程序,输出将是:

    First character is: ello Everyon
    

    这里在String类中增加了一个扩展函数removeFirstLastChar()。

    类名是接收者类型(在我们的例子中是字符串类)。扩展函数中的 this 关键字引用了接收者对象。

    【讨论】:

      猜你喜欢
      • 2022-12-19
      • 2018-09-27
      • 2011-06-22
      • 2015-12-17
      • 1970-01-01
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多