kotlin - Kotlin 函数引用是否有一个简单的空安全运算符?
问题描述
我想在可空对象上传递函数引用。以 Android 为例,假设我想使用Activity#onBackPressed
该活动的子片段。
如果我想调用这个函数,我可以很容易地做到
activity?.onBackPressed()
但是,假设我想将其作为参考传递:
val onBackPressedRef = activity::onBackPressed
这给出了只允许安全或非空断言调用的熟悉的空安全错误......
我可以通过以下方式消除错误,但使用!!
显然并不理想:
val onBackPressedRef = activity!!::onBackPressed
尝试activity?::onBackPressed
是我的第一直觉,但这也因几个错误而中断,口译员似乎感到困惑。
val onBackPressedRef = activity?.let { it::onBackPressed }
最后一个变体有效,但它比仅使用?::
. 我检查了所有我能找到的文档,但我觉得我错过了一些东西。有任何想法吗?
解决方案
?::
你是对的, Kotlin中没有运算符。
您有几种选择:
1.let
和run
因此,您必须使用辅助函数。代替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() }
这为非空函数变量交换了不同的语法:
// activity can be null
val onBackPressedRef = funcRef(activity, Activity::onBackPressed)
// Callable directly
onBackPressedRef()
推荐阅读
- c# - 方法 'IndexOf' 没有重载需要 1 个参数。在 .NET 框架下工作,但不在 .NET Core 下工作
- javascript - 设置正确的正则表达式
- html - Internet Explorer 11 屏幕阅读器辅助功能问题
- java - 在缓冲区阅读器 Java 中添加行计数器
- python - 如何使用新的键和值创建字典并将值添加到一个键
- microsoft-graph-api - 图形邮件 API:504 网关超时错误
- groovy - 获取从节点可到达的顶点(在可变深度)
- regex - 使用字段分隔符在 bash 中替换 Perl 字符串 - 跳过标题行
- java - 为什么 getName 不包含在 java.lang.reflect.AccessibleObject 接口中?
- python - 对数曲线拟合不适合我的数据