【发布时间】:2023-04-09 00:56:02
【问题描述】:
我很好奇在 Kotlin 中定义成员函数的建议方法是什么。考虑这两个成员函数:
class A {
fun f(x: Int) = 42
val g = fun(x: Int) = 42
}
这些似乎完成了同样的事情,但我发现了细微的差别。
例如,基于val 的定义在某些情况下似乎更加灵活。也就是说,我无法找到一种直接的方式来将f 与其他功能组合在一起,但我可以使用g。为了玩弄这些定义,我使用了funKTionale 库。我发现这不能编译:
val z = g andThen A::f // f is a member function
但是如果f 被定义为指向同一个函数的val,它就可以编译得很好。为了弄清楚发生了什么,我要求 IntelliJ 为我明确定义 ::f 和 g 的类型,它给了我这个:
val fref: KFunction1<Int, Int> = ::f
val gref: (Int) -> Int = g
所以一个是KFunction1<Int, Int> 类型,另一个是(Int) -> Int 类型。很容易看出,两者都代表Int -> Int类型的函数。
这两种类型有什么区别,在哪些情况下很重要?我注意到对于顶级函数,我可以使用任何一个定义来很好地组合它们,但是为了使上述组合能够编译,我必须这样写:
val z = g andThen A::f.partially1(this)
即我必须先将其部分应用到this。
既然在函数中使用vals 时我不必经历这些麻烦,我是否有理由使用fun 定义非单元成员函数?是否存在我遗漏的性能或语义差异?
【问题讨论】:
-
关于 vals 的一个重要问题是缺乏参数性,这无法编译:
val id = fun<T>(t:T) = t -
啊,好点子!没想到。绝对值得考虑。
-
g 是否有权访问实例属性?
-
@JacobZimmerman 确实如此,尽管从我的示例中确实不明显。感谢您指出。
标签: kotlin