一个具有通用返回类型的函数

15

是否有可能编写一个返回通用类型的函数?像这样:

fun <T> doSomething() : T {
    when {
        T is Boolean -> somethingThatReturnsBoolean()
        T is Int -> somethingThatReturnsInt()
        else -> throw Exception("Unhandled return type")
    }
}
4个回答

27
您可以使用具体化类型来捕获其类字面值,例如:
inline fun <reified T> doSomething() : T {
    return when (T::class.java) {
        Boolean::class.java -> somethingThatReturnsBoolean() as T
        Int::class.java -> somethingThatReturnsInt() as T
        else -> throw Exception("Unhandled return type")
    }
}

但是你还必须通过未经检查的转换,使编译器相信T是布尔类型或整型,就像示例中一样。

reified可以让真实的T类型可访问,但只能在内联函数内使用。如果你想要一个普通函数,你可以尝试:

inline fun <reified T> doSomething() : T = doSomething(T::class.java)
fun <T> doSomething(klass: Class<T>): T {
    return when (klass) { ... }
}

但如果函数返回类型为布尔值或整数,则会出现编译问题,因为该函数没有返回。 - zt1983811
1
谢谢@zt1983811,我已经添加了return语句。 - Miha_x64
我该如何调用这个布尔值方法? - C96

1
您还可以直接将函数(如somethingThatReturnsInt())传递给通用函数,并从传递的函数本身推断返回类型。以下是Kotlin示例:
// This function takes any method you provide and infers the result-type
public fun<T> generic_function(passed_function: () -> T): T? =
    passed_function()


// Pass your function. The return type will be inferred directly from somethingThatReturnsInt()'s return-type
val res: Int? = generic_function(::somethingThatReturnsInt)

// For the sake of completeness, this is valid as well
val res: Int? = generic_function<Int?> { somethingThatReturnsInt() }

这样,您就不必处理“when”场景,并且返回类型根据传递的函数是通用的。

0
嗯,其实有一种方法可以做到这样的事情,但是感觉有点麻烦:
data class Coffee(val milk: Double, val sugar: Int)

class ComparingBuilder(val oldInstance: Coffee, val updatedInstance: Coffee) {
     operator fun <T> invoke(accessor: Coffee.() -> T?): T? =
         if (whatever) { oldInstance.accessor() }
         else { updatedSupplier.accessor() }
}

fun useComparingBuilder(
    oldInstance: Coffee,
    updatedInstance: Coffee,
) = OptionalBuilder(oldInstance, updatedInstance).let { builder ->
    val remixedCoffee = Coffee(
        milk = builder { milk },
        sugar = builder { sugar },
    )
}

简而言之,这不是制作通用lambda的方法,但它是一种可以使用某些东西就像它是通用lambda的方法。

很难用语言表达清楚,希望代码更加清晰明了....


0

Any 可能是你想要使用的东西。它是 Kotlin 类层次结构的根。

同时,Any? 语法也可用于 Any

fun doSomething(key: Any): Any {
    when {
             key is Boolean -> return true
             key is Int -> return 1
             else -> throw Exception("Unhandled return type")
         }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接