Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function returning ad-hoc object in Kotlin

Tags:

kotlin

Currently I have a private function which returns a Pair<User, User> object. The first user is the sender of something, the second user is the receiver of that thing.

I think this Pair<User, User> is not enough self explanatory - or clean if you like - even though it's just a private function.

Is it possible to return with an ad-hoc object like this:

private fun findUsers(instanceWrapper: ExceptionInstanceWrapper): Any {
    return object {
        val sender = userCrud.findOne(instanceWrapper.fromWho)
        val receiver = userCrud.findOne(instanceWrapper.toWho)
    }
}

and use the returned value like this:

// ...
val users = findUsers(instanceWrapper)
users.sender // ...
users.receiver // ...
// ...

?

If not, what's the point of ad-hoc object in Kotlin?

like image 835
LordScone Avatar asked Jul 20 '26 05:07

LordScone


2 Answers

Since the type can not be denoted in the language, use return type inference:

class Example {
    private fun findUsers(instanceWrapper: ExceptionInstanceWrapper) =
        object {
            val sender = userCrud.findOne(instanceWrapper.fromWho)
            val receiver = userCrud.findOne(instanceWrapper.toWho)
        }

    fun foo() = findUsers(ExceptionInstanceWrapper()).sender
}

Another option would be to devise a data class:

class Example {
    private data class Users(val sender: User, val receiver: User)
    private fun findUsers(instanceWrapper: ExceptionInstanceWrapper): Users {
        return Users(
            sender = userCrud.findOne(instanceWrapper.fromWho),
            receiver = userCrud.findOne(instanceWrapper.toWho)
        )
    }

    fun foo() = findUsers(ExceptionInstanceWrapper()).sender
}
like image 133
Andrey Breslav Avatar answered Jul 22 '26 18:07

Andrey Breslav


Simply define your function as a lambda.

Here's simple object I've just written as an example in another context:

private val Map = {
    val data = IntArray(400)

    for (index in data.indices) {
        data[index] = index * 3
    }

    object {
        val get = { x: Int, y: Int ->
            data[y * 20 + x]
        }
    }
}

fun main() {
    val map = Map()
    println(map.get(12,1))
}

Unfortunately, you cannot assign a type name, so it can be used as a return value but not as an argument. Maybe they'll make this possible so we can finally do OOP JS style.

Alternatively, they could implement object types equivalent to function types but that could end up being too wordy. You could then do a typedef but that would actually just be a kind of class definition 😅

like image 29
yeoman Avatar answered Jul 22 '26 19:07

yeoman