在 Scala 方法中返回 Class 类型的选项

Returning Options of Class types in Scala methods

我正在努力处理我正在写的东西的 Class 类型,答案可能涉及泛型,但我对正确的解决方案应该是什么感到困惑。

我有一个 Scala class Vehicle 有几个 child classes (Car, Bus, Train, Motorcycle, 等等):

class Vehicle {
    ...
}

class Car extends Vehicle {
    ...
}

class Motorcycle extends Vehicle {
    ...
}

我现在正在尝试编写一个实用方法,可以将字符串映射到 Vehicle subclass(即 Class不是那个class的实例):

object VehicleUtils {
    def mapToVehicleType(vehicleType : String) : Vehicle = {
        var vType : Vehicle = null
        if(vehicleType == "car") {
            vType = Car
        } else if(vehicleType == "motorcycle") {
            vtype = Motorcycle
        } else if(...) {
            ...etc.
        }

        vType
    }
}

问题是我 confusing/blurring 类型与实例。我不希望 mapToVehicleType 方法到 return 一个 实例 ,比方说,Car。我希望它简单地 return Car class 如果“car”作为输入提供,等等。任何人都可以发现我在哪里出错以及解决方案是什么.如果可能的话,我也想使用 Scala Options,因为 mapToVehicleType 方法当然可以 return null.

Scala 提供 classOf[T] 来获取 class 类型的 class。例如:classOf[Car] returns 类型的实例 Class[Car].

为了映射到适当的 class 类型,您可以使用模式匹配将类型从提供的字符串映射到 Option:

def mapToVehicleType(vehicleType: String): Option[Class[_ <: Vehicle]] = {
    vehicleType match {
        case "car"        => Some(classOf[Car])
        case "motorcycle" => Some(classOf[Motorcycle])
        case _            => None
    }
}

为什么要 class?这真的是关键问题。如果您要使用反射动态实例化,您可能会考虑不同的模式。

反射是经常用来克服 Java 限制的事物之一(我假设您来自 Java)。但是 Scala 中通常有更好的模式。

您可以 return class(例如 classOf[Car]),但请考虑更好的算法。

假设,为了便于讨论,您将 returnclass 作为 "factory"。我不确定这是最好的模式,但你可以考虑这样的事情而不是反思:

object GetVehicleCreator {
  def apply(vehicleType: String): Option[() => Vehicle] = vehicleType match {
    case "car" =>
      Some(() => new Car)
    case "motorcycle" =>
      Some(() => new Motorcycle)
    case _ =>
      None
  }
}

请注意,它不是 "utils" 对象。 "utils" 的使用是 Scala IMO 中的一种反模式(老实说,我也不喜欢 Java 中的这种模式)。只需创建一个函数。任何带有 apply 方法的东西都是一个函数。使用:

val vehicleOption: Option[Vehicle] = for {
  fn <- GetVehicleFactory("car")
  vehicle <- fn()
} yield vehicle

...但是我必须再次知道您想要完成什么。我敢打赌有更好的模式。