gpt4 book ai didi

kotlin - 在reduce()内部使用扩展函数引用

转载 作者:行者123 更新时间:2023-12-02 02:19:08 25 4
gpt4 key购买 nike

假设:

val sets = listOf(setOf(1, 2, 3), setOf(2, 3, 4), setOf(3, 4, 5))

为什么这在 Kotlin 1.2 中是非法的?

val unionOfSets = sets.reduce(Set<Int>::union)  // == setOf(1, 2, 3, 4, 5)

这不应该是等价的吗?

val unionOfSets = sets.reduce { acc, set -> acc.union(set) }

来自https://kotlinlang.org/docs/reference/lambdas.html :

Non-literal values of function types with and without receiver are interchangeable, so that the receiver can stand in for the first parameter, and vice versa. For instance, a value of type (A, B) -> C can be passed or assigned where a A.(B) -> C is expected and the other way around

最佳答案

Kotlin 似乎没有在接收器上成功进行类型推断,可能是因为所有模板的原因(Kotlin 对类型没有任何保证)。

但是您可以通过传递对调用可调用的引用来解决它:

fun main(args: Array<String>) {
val sets = listOf(setOf(1,2,3), setOf(4,5,6), setOf(7,8,9))
val unionOfSets = sets.reduce(Set<Int>::union::invoke)

println(unionOfSets)
}

更新:这就是sets.reduce(Set::union)不起作用的原因

Kotlin 使用智能转换来解析接收者(参见 https://github.com/JetBrains/kotlin/blob/143c3ccb95f93299233ade88c24b2fa2b9b29abf/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt 第 553 行)

但只有在文档 ( https://kotlinlang.org/docs/reference/typecasts.html#smart-casts ) 中提到的类型得到保证的情况下,智能转换才能工作:

Note that smart casts do not work when the compiler cannot guarantee that the variable cannot change between the check and the usage.

编译器尝试找到正确的接收器(通过智能转换),但无法做到这一点,因为编译器无法保证 acc 变量不会更改。这是由于嵌套泛型所致:您有一个 List<Set<Int>>这将是List<*>在运行时。

这就是为什么我们可以使用 invoke 来代替。 Invoke 是在构建时生成的运算符方法,并且是类型安全的(不需要智能转换)。

关于kotlin - 在reduce()内部使用扩展函数引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51836195/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com