是否有用于Kotlin函数引用的简单的null安全运算符?

时间:2019-11-11 21:43:43

标签: kotlin

我想在可为空的对象上传递函数引用。以Android为例,假设我要使用来自该活动子项的片段中的Activity#onBackPressed

如果我想调用此功能,我可以轻松完成

activity?.onBackPressed()

但是,说我想通过它作为参考:

val onBackPressedRef = activity::onBackPressed

这给出了常见的null安全错误仅允许安全或非null断言的呼叫...


我可以通过以下方法消除错误,但使用!!显然不是理想选择:

val onBackPressedRef = activity!!::onBackPressed

尝试activity?::onBackPressed是我的第一个本能,但这也因几个错误而中断,解释器看起来很困惑。

val onBackPressedRef = activity?.let { it::onBackPressed } 

这最后一个变种可行,但它比仅使用?::丑陋得多。我检查了所有可以找到的文档,但感觉好像丢失了一些东西。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

是的,在Kotlin中没有?::运算符。
您有几种选择:

1。 letrun

因此,您必须使用帮助器功能。除了使用let()之外,您还可以使用run()来简化表达式:

val onBackPressedRef = activity?.let { it::onBackPressed }
val onBackPressedRef = activity?.run { ::onBackPressed }

但是请记住,无论哪种方式,调用也会变得更加冗长:

onBackPressedRef?.invoke(args)

因此,您应该问自己,这是否确实是您想要的,或者是否也可以接受无操作函数调用。

2。封闭

您可以使用闭包-但这会改变语义:

val onBackPressedRef = { activity?.onBackPressed() }

在这里,onBackPressedRef不再可以为空,因此您可以使用()运算符来调用它,并且在activity为空的情况下将无效。

3。辅助功能

如果您经常遇到带有可空对象的函数引用,则可以编写自己的小抽象:

// Return type: () -> Unit
fun <T> funcRef(obj: T?, function: T.() -> Unit) = { obj?.function() }

这为非null函数变量交换了不同的语法:

 // activity can be null
 val onBackPressedRef = funcRef(activity, Activity::onBackPressed)

 // Callable directly
 onBackPressedRef()