ASSUM I具有以下扩展功能:

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

我可以非常方便地用类似于s.getPrivateProperty<Int>("height")的东西来调用它,这是一个类型为Int的表达式.

现在,我想确保该函数只在非可选类型上定义.我使用了绝对不可为空的符号:

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

这达到了目的,但是,因为我有一个必须显式的类型参数,所以现在我实际上必须同时给出这两个参数.例如:s.getPrivateProperty<Shape, Int>("height").

有可能避免那in general美元吗?有没有其他方法可以避免here,即只在非可选类型上定义扩展函数?

推荐答案

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

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

在Kotlin 1.7之前,在调用函数时,必须指定<...>部分中的所有类型参数,或者必须让所有参数都被推断出来.

不过,在这种情况下,有are种方法可以推断出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>.

Kotlin相关问答推荐

最好的方法来创建一个 map 在kotlin从两个列表

collectAsState 未从存储库接收更改

如何更改默认推断没有接收者的函数类型?

kotlin短路列表判断吗?

Ktor 在 Heroku 上的 CORS 问题,但在本地没有

找不到有效的 Docker 环境

Kotlin SIZE_BYTES

Kotlin 接口类型参数

Kotlin中用于调用常量名称的枚举类方法之间的区别

如何在 Kotlin 中为变量分配另一个变量的值?

是否可以通过超时暂停协程?

IntentService (kotlin) 的默认构造函数

如何使用 Kotlin Coroutines 使 setOnClickListener debounce 1 秒?

将协同路由调用放在存储库或ViewModel中哪个更好?

Android:在 DAO 中使用 Room 数据库和 LiveData 架构

在 Kotlin 中创建 Spinner 时,如何在 Fragment 中的旋转屏幕上修复指定为非空的参数为空?

kotlin中密封类和密封接口的区别是什么

将 androidx.constraintlayout:constraintlayout lib 更新到 2.0.2 版本后出现崩溃 isRtl () null 引用

在Kotlin中创建通用二维数组

任务':app:kaptDebugKotlin'的Kotlin执行失败