Scala:如何使函数的返回类型通用并依赖于运行时参数?

Bar*_*Bar 1 reflection polymorphism scala

说我有:

class Animal
class Bird extends Animal
class Dog extends Animal
Run Code Online (Sandbox Code Playgroud)

如何根据提供的参数编写返回运行时类型(Bird 或 Dog)的函数。

我正在尝试类似的东西:

import scala.reflect.ClassTag
def createAnimal[T <: Animal : ClassTag](doesItBark: Boolean): T = {
    if (doesItBark) return new Dog()
    else return new Bird()
}


val azor = createAnimal(doesItBark = true) //azor's type should be Dog
Run Code Online (Sandbox Code Playgroud)

哪个不起作用。

有可能在 Scala 中做这样的事情吗?

Mic*_*jac 5

这是不可能的。在编译时必须知道方法的返回类型,即它返回 type T。但是,类型参数T必须在调用方法时确定,而不是在 之后确定。调用者必须事先知道类型,所以在这里你能做的最好的事情是 return Animal

val newAnimal: ??? = createAnimal(runtimeParam)
           //   ^ What type goes here? 
           //     The compiler needs to infer it, but it can't that way
Run Code Online (Sandbox Code Playgroud)

因此,打电话时createAnimal你需要期待DogBirdAnimal。因为你不知道那可能是什么,你只能说它是一个Animal. 如有必要,您可以稍后使用类型测试来检查您返回的内容。

除非您自己填写,否则类型参数不会执行任何操作。否则,你应该只有:

def createAnimal(doesItBark: Boolean): Animal = {
    if (doesItBark) return new Dog()
    else return new Bird()
}
Run Code Online (Sandbox Code Playgroud)