我可以在Kotlin中混合使用推断和exlicit泛型类型参数吗?

4xrmg8kj  于 2023-06-24  发布在  Kotlin
关注(0)|答案(2)|浏览(136)

假设我有这个扩展函数:

inline fun <reified R> Any.getPrivateProperty(variableName: String): R { … }

我可以很方便地用类似s.getPrivateProperty<Int>("height")的东西调用它,这是一个Int类型的表达式。
现在我想确保函数只定义在非可选类型上。我使用了definitely-not-nullable表示法:

inline fun <T: Any, reified R> T.getPrivateProperty(variableName: String): R { … }

这就达到了目的,但是,因为我有一个类型参数,它必须是显式的,我现在实际上必须给予两个参数。例如:s.getPrivateProperty<Shape, Int>("height")
有没有可能避免这种情况 * 在一般情况下 *?有没有一种替代方法来避免 here,也就是说,只在非可选类型上定义扩展函数?

k3bvogb1

k3bvogb11#

在早期版本的Kotlin中,不能混合使用推断类型和指定类型参数;但是Kotlin1.7.0为类型参数引入了一个下划线运算符,它允许你这样做。
下划线表示未指定的类型,其方式类似于它在函数形参列表或解构声明中的方式。
在这种情况下,你可以用途:

s.getPrivateProperty<_, Int>("height")

而不是:

s.getPrivateProperty<Shape, Int>("height")

(As Sweeper的回答解释说,fun Any.getPrivateProperty(…)已经定义为只用于不可空的接收器,所以你可能不需要它。

nc1teljy

nc1teljy2#

函数 already 的第一个版本不适用于可空类型。例如,这不会编译。

val x: String? = "foo"
val y = x.getPrivateProperty<String>("foo")

在Kotlin1.7之前,当调用一个函数时,你必须在<...>部分指定所有类型参数,或者你必须让它们全部被推断出来。
不过,在这种情况下,有**种方法可以推断R。它不需要总是用<>来写。只需执行以下操作:

val y: String = x.getPrivateProperty("foo")
//     ^^^^^^

也就是说,因为R是返回类型,所以你可以把它写成你要赋值的变量的类型。
对于非返回类型,如果由于某种原因Kotlin无法推断它们,那么“推断”它们的一种简单方法是传递一个Dummy<T>,让调用者指定。

class Dummy<T>

// imagine foo having some other parameters using T and U, 
// but T can't be inferred for whatever reason, but U can be inferred
// you can just add an extra parameter of type Dummy<T>
fun <T, U> foo(... other parameters ..., t: Dummy<T>) { ... }

然后呼叫者可以这样做:

foo(..., Dummy<SomeType>())

而不必指定U
对于不可空的类型参数,可以使用KClass<T>,而不是创建自己的Dummy<T>

相关问题