Kotlin函数作为Map值

5

在Java中,您可以拥有:

final Map<String, Supplier<Interface>> associations = new HashMap<>();
associations.put("first", One::new);
associations.put("second", Two::new);

在 Kotlin 中,这意味着:
val associations: MutableMap<String, Supplier<Interface>> = HashMap()
associations["first"] = Supplier(::One)
associations["second"] = Supplier(::Two)

没有使用kotlin-reflect,这是唯一的方法还是我遗漏了什么?在我看来,这看起来不太好,也不符合Kotlin的风格。

由于出现了推断错误,这是完整的代码:

fun example() {
   val associations: MutableMap<String, Supplier<Interface>> = HashMap()
   associations["first"] = Supplier(::One)
   associations["second"] = Supplier(::Two)
}

interface Interface
class One : Interface
class Two : Interface

InterfaceOne/Two是如何定义的?你尝试过像associations["first"] = { One }这样的东西吗? - msrd0
1
有趣的是,我得到了两个“类型推断失败”的错误,一个针对每个赋值操作。 - msrd0
1
我在 https://try.kotlinlang.org 上尝试了一下,不得不将其更改为 Supplier<out Interface> 才能使其正常工作。 - msrd0
1
我不确定我理解这里的问题。Kotlin不是Unix,你不需要把所有东西都塞进两个字母里。{ One() } 对我来说看起来很好。 - Abhijit Sarkar
@AbhijitSarkar,生成的字节码有所不同。 - LppEdd
显示剩余4条评论
2个回答

4
更加具有Kotlin风格的替代方案可能是:
val associations: MutableMap<String, Supplier<out Interface>> = hashMapOf(
    "first" to Supplier(::One), 
    "second" to Supplier(::Two)
)

associations如果没有在其他地方被修改,可能就不需要再被改变了。

同时,将Supplier替换为一个Kotlin高阶函数。

val associations: Map<String, () -> Interface> = hashMapOf(
    "first" to ::One,
    "second" to ::Two
)

1
假设您不一定需要一个 Supplier 的实例,而只是需要一个新的函数,那么您可以选择其中任何一个版本。
val associations: MutableMap<String, () -> Interface> = HashMap()
associations["first"] = { One() }
associations.set("second") { Two() }

他们并不完美,但在我看来比Supplier(::One)更好。

1
但这涉及到创建第二个“包装”函数,而不是直接引用构造函数。 - LppEdd
没错,通常我会认为编译器会将其优化掉,但是对于JVM语言,我并不确定是否会发生这种情况,因此你最好使用 ::One - msrd0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接