我想在可为空的对象上传递函数引用。以Android为例,假设我要使用来自该活动子项的片段中的Activity#onBackPressed
。
如果我想调用此功能,我可以轻松完成
activity?.onBackPressed()
但是,说我想通过它作为参考:
val onBackPressedRef = activity::onBackPressed
这给出了常见的null安全错误仅允许安全或非null断言的呼叫...
我可以通过以下方法消除错误,但使用!!
显然不是理想选择:
val onBackPressedRef = activity!!::onBackPressed
尝试activity?::onBackPressed
是我的第一个本能,但这也因几个错误而中断,解释器看起来很困惑。
val onBackPressedRef = activity?.let { it::onBackPressed }
这最后一个变种可行,但它比仅使用?::
丑陋得多。我检查了所有可以找到的文档,但感觉好像丢失了一些东西。有什么想法吗?
答案 0 :(得分:4)
是的,在Kotlin中没有?::
运算符。
您有几种选择:
let
和run
因此,您必须使用帮助器功能。除了使用let()
之外,您还可以使用run()
来简化表达式:
val onBackPressedRef = activity?.let { it::onBackPressed }
val onBackPressedRef = activity?.run { ::onBackPressed }
但是请记住,无论哪种方式,调用也会变得更加冗长:
onBackPressedRef?.invoke(args)
因此,您应该问自己,这是否确实是您想要的,或者是否也可以接受无操作函数调用。
您可以使用闭包-但这会改变语义:
val onBackPressedRef = { activity?.onBackPressed() }
在这里,onBackPressedRef
不再可以为空,因此您可以使用()
运算符来调用它,并且在activity
为空的情况下将无效。
如果您经常遇到带有可空对象的函数引用,则可以编写自己的小抽象:
// 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()