在Kotlin中的when子句中合并多个

时间:2018-11-16 12:57:34

标签: generics kotlin

假设我有以下内容:

fun makeSound(val animal: Animal) = when(animal) {
  is Lion -> animal.roar()
  is TRex -> animal.roar()
  is Cow -> animal.moo()
}

通常,我将通过添加一个RoaringAnimal接口并询问is RoaringAnimal来简化此过程。但是,还有另一种方式可以将多个is子句组合成一个子句吗?

4 个答案:

答案 0 :(得分:4)

更新:下面的答案是在问题指定roaranimal参数的方法之前写的。现在的问题仍然存在,下面的答案将不再起作用,但是仍然显示了如何在when语句中将多个条件合并为一行。

您可以将它们组合在一起

fun makeSound(animal: Animal) = when(animal) {
  is Lion, is TRex -> roar()
  is Cow -> moo()
}

答案 1 :(得分:2)

通常,您可以按照Yoni的答案所示组合这些子句。

但是在特定情况下,roar是在LionTRex上定义的,但不是在Animal上定义的,则不能。

这是因为编译器插入了智能强制类型转换:

is Lion -> animal.roar()

是真的

is Lion -> (animal as Lion).roar()

但是在is Lion, is TRex ->子句中,它不知道要插入的强制转换。

原则上,可以通过插入另一个when来扩展编译器以处理此类情况:

is Lion, is TRex -> animal.roar()

将成为

is Lion, is TRex -> when(animal) {
    is Lion -> animal.roar() // works as before
    is TRex -> animal.roar()
}

但我不希望这种情况发生

答案 2 :(得分:1)

fun makeSound(val animal: Animal) = when(animal) {
  Lion, TRex -> animal.roar()
  Cow -> animal.moo()
}

你不需要“是”。只需将逗号分隔符用作 OR 即可。

答案 3 :(得分:0)

您在这里所做的事情对我来说像是code smell。为什么不对这种类型的问题使用多态呢?

interface Animal {
    fun makeSound()
}
class Lion : Animal {
    override fun makeSound() { println("roar") }
}
class Trex : Animal {
    override fun makeSound() { println("ROAAAARRRR") }
}
class Cow : Animal {
    override fun makeSound() { println("moo") }
}

fun makeSound(animal: Animal) {
    animal.makeSound()
    // due tue "late binding", this will automatically call the correct method - no need to check what kind of animal it is! 
}