Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics Combine multiple在Kotlin的when子句中_Generics_Kotlin - Fatal编程技术网

Generics Combine multiple在Kotlin的when子句中

Generics Combine multiple在Kotlin的when子句中,generics,kotlin,Generics,Kotlin,假设我有以下几点: fun makeSound(val animal: Animal) = when(animal) { is Lion -> animal.roar() is TRex -> animal.roar() is Cow -> animal.moo() } 通常我会简单地添加一个rowinganimal接口并询问是rowinganimal,从而简化这个过程。但是有没有另一种方法可以将多个is子句组合成一个呢?更新:下面的答案是在问题指定咆哮是关于动物

假设我有以下几点:

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

通常我会简单地添加一个
rowinganimal
接口并询问
是rowinganimal
,从而简化这个过程。但是有没有另一种方法可以将多个
is
子句组合成一个呢?

更新:下面的答案是在问题指定
咆哮
是关于
动物
参数的方法之前写的。现在的问题是,下面的答案将不再有效,但是它仍然显示了当语句时,如何在一行中组合多个条件

您可以将它们组合在一起:

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

通常情况下,您可以将Yoni的答案中所示的子句组合在一起

但是在特定情况下,
roar
是在
Lion
TRex
上定义的,而不是在
Animal
上定义的,您不能这样做

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

is Lion -> animal.roar()
真是

is Lion -> (animal as Lion).roar()
但在
is Lion,is TRex->
子句中,它不知道要插入什么类型的强制转换


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

is Lion, is TRex -> animal.roar()
将成为

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

但我不希望发生这种事

你在这里做的事对我来说是个大麻烦。为什么不使用多态性来解决这类问题

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! 
}

你不需要“是”。只需在此处使用逗号分隔符即可。

这将如何工作?这不只是捕捉一种普通的
动物
类型吗?
吼叫
只有在您传入
狮子
特雷克斯
时才会被调用。你说的“抓”到底是什么意思?我想知道你是否需要稍微澄清一下你的问题?啊,是的。我的问题不准确。我现在修改了它。正如Alexey所说,现在你已经更新了你的问题,指定
roar
Lion
TRex
上的一种方法,那么不,没有新的接口或基类,就没有(好的)方法可以做到这一点。(你可以使用反射,但这不是一个好主意。)为什么你想要结合
is Lion
is TRex
的东西?按照你所展示的方式使用它难道还不够简单吗?否则,我宁愿更新您的层次结构,如果可能的话。。。(旁注:
val
在这里可能是错误的,
=
需要一个详尽的
时)。正如我在问题中所说,使用接口是完全可能的。然而,问题不在于最佳实践,而在于Kotlin中可能出现的情况。“原则上,编译器可以扩展以处理此类情况……”是的,实际上这正是我所认为的行为。感谢您解释编译器不知道要插入哪个智能强制转换。
fun makeSound(val animal: Animal) = when(animal) {
  Lion, TRex -> animal.roar()
  Cow -> animal.moo()
}