Druckles
Druckles

Reputation: 3782

How to use an extension function in a companion object

Is it possible to define and use an extension function in a class' companion object?

In this example removePadding() is the extension function being used in 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?
}

The extension function removePadding() may look like:

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

And the parse function may be called as:

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

If it's possible, how? If it's not, why not?

Upvotes: 3

Views: 205

Answers (2)

hotkey
hotkey

Reputation: 147901

You could basically place the extension in any of those places, declaring it normally:

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

The private modifier limits the visibility to the companion object or the data class, depending on where you place it. Usually, one should prefer the narrowest possible visibility scope for a declaration.

And another option is to declare the extension function locally in the parse function (note that it doesn't have the visibility modifier this time):

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) }
        }
    }
}

Upvotes: 2

Frank Neblung
Frank Neblung

Reputation: 3165

Since you only need the function as a helper for parse, you should declare it next to it.

companion object {
    private fun String.removeWhitespace() = replace("\\s+".toRegex(), "")

    fun parse(text: String?): Point? {
        ...

Upvotes: 1

Related Questions