java - Kotlin 1.3.61 无法解析函数文字上扩展属性的返回类型
问题描述
在下面的示例中,我编写了简单的装饰器扩展来捕获异常并返回null
任何错误。问题是num1
和num2
类型被推断为R?
而不是Double?
:
val <R> (()->R).nothrow: (()->R?) get() = { try { invoke() } catch(ex: Throwable) { null } }
fun main() {
val num1 = "42"::toDouble.nothrow()
println(num1)
val num2 = "english"::toDouble.nothrow()
println(num2)
}
程序输出为:
42.0
null
但是当我写
num1!! + 3.14
我得到错误:
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch
候选人都是现有的plus
运营商。
扩展的反编译java代码nothrow
如下:
@NotNull
public static final Function0 getNothrow(@NotNull Function0 $this$nothrow) {
int $i$f$getNothrow = 0;
Intrinsics.checkParameterIsNotNull($this$nothrow, "$this$nothrow");
return (Function0)(new Function0($this$nothrow) {
// $FF: synthetic field
final Function0 $this_nothrow;
@Nullable
public final Object invoke() {
Object var1;
try {
var1 = this.$this_nothrow.invoke();
} catch (Throwable var3) {
var1 = null;
}
return var1;
}
public {
this.$this_nothrow = var1;
}
});
}
这是为什么?
编辑
问题似乎在于扩展属性:
解决方案
如果您在调用的函数周围添加括号,它是固定的:
val num1 = ("42"::toDouble.nothrow)()
println(num1)
val num2 = ("english"::toDouble.nothrow)()
println(num2)
num1!! + 3.14 // Does not fail
如果您尝试在 IDEA 中编写此代码:
"42"::toDouble()
它说:
此语法保留供将来使用;要调用引用,请将其括在括号中: (foo::bar)(args)
这就是你的代码失败的原因。您的代码只是比调用引用更棘手,因此 IDEA 无法检测到它。
推荐阅读
- sql - 获取不匹配的输入 '') 作为 '' 期望
- c++ - 委托构造函数不能有其他内存初始化器 - 错误
- flask - Flask - 返回提交的相同表单
- c# - 有没有办法让 Cinemachine 在被销毁并实例化为克隆后重新定位播放器?
- go - 在浏览器中本地查看包文档
- ios - 如何使用 BLE+BT 通过 iPhone 上的其他蓝牙设备阅读和回复任何通知(任何应用程序通知)
- apache-spark - Spark DataFrame 中是否有 aggregateByKey 函数?
- html - 如何在 Bootsrap4 中的列之间添加边距?
- python - 在 Docker 容器中设置 Flask Session 的权限
- python - Python 使用内部 CA 请求 SSLError