【问题标题】:How to use an extension function in a companion object如何在伴随对象中使用扩展函数
【发布时间】:2019-11-15 13:05:52
【问题描述】:

是否可以在类的伴生对象中定义和使用扩展函数?

在此示例中,removePadding()Point.parse() 中使用的扩展函数。

data class Point(private var x: Int, private var y: Int) {
    companion object {
        fun parse(text: String?) = text?.removePadding()
            ?.let { "(\\d+),(\\d+)".toRegex().find(it) }
            ?.mapNotNull { it.toIntOrNull() }
            ?.let { Point(it[0], it[1]) }

        // define removePadding() here?
    }

    // define removePadding() here?
}

扩展函数removePadding() 可能如下所示:

fun String.removePadding() = this.replace("\\s+".toRegex(), "")

parse 函数可以这样调用:

val one = Point.parse("1, 7")

如果可能,怎么做?如果不是,为什么不呢?

【问题讨论】:

  • 既然它应该是String的扩展函数,它不应该在data class之内,而是在范围之外。我还认为replace("\\s#") 无法编译,您没有为任意数量的空格提供替换String

标签: kotlin extension-methods


【解决方案1】:

您基本上可以将扩展名放在任何这些地方,并正常声明:

private fun String.removePadding() = this.replace("\\s+".toRegex(), "")

private 修饰符将可见性限制为伴随对象或 data 类,具体取决于您放置它的位置。通常,人们应该更喜欢声明的最窄可见范围。

另一种选择是在parse函数中本地声明扩展函数(注意这次它没有可见性修饰符):

data class Point(private var x: Int, private var y: Int) {
    companion object {
        fun parse(text: String?): Point? {
            fun String.removePadding() = this.replace("\\s+".toRegex(), "")

            return text?.removePadding()
                ?.let { "(\\d+),(\\d+)".toRegex().find(it) }
                ?.groupValues?.map { it.toIntOrNull() ?: return null }
                ?.let { (x, y) -> Point(x, y) }
        }
    }
}

【讨论】:

    【解决方案2】:

    由于您只需要该函数作为parse 的助手,因此您应该在它旁边声明它。

    companion object {
        private fun String.removeWhitespace() = replace("\\s+".toRegex(), "")
    
        fun parse(text: String?): Point? {
            ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多