2016-09-29 76 views
1

我正在努力处理Class类型的东西,我写的东西,答案可能涉及泛型,但我很困扰什么是正确的解决方案。在Scala方法中返回类类型的选项

我有一个具有多个子类(CarBusTrainMotorcycle等)的Scala类Vehicle

class Vehicle { 
    ... 
} 

class Car extends Vehicle { 
    ... 
} 

class Motorcycle extends Vehicle { 
    ... 
} 

我现在想写一个工具方法,可以映射到字符串一个子类Vehicle(即,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 
    } 
} 

问题是我混淆/模糊类型与实例。我不希望mapToVehicleType方法返回例如Car实例。如果提供“car”作为输入等,我希望它仅返回Car类。任何人都可以发现我要去哪里以及解决方案是什么。如果可能的话,我也想使用Scala Options,因为mapToVehicleType方法肯定可以返回null

+0

您能更具体地了解您正在尝试做什么吗?你的方法返回一个'Vehicle'类型的对象,而不是一个类(类型)。类(类型)不是对象,不能被返回,它们存在于并行的宇宙中。 –

回答

2

Scala提供classOf[T]以获取类的类类型。例如:classOf[Car]返回Class[Car]类型的实例。

用于映射到相应的类类型,你可以使用模式匹配的类型从提供的字符串映射到Option

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

为什么你想要的类?这确实是关键问题。如果你打算动态实例化使用反射,你可能会考虑一个不同的模式。

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

您可以返回类(例如classOf [Car]),但考虑更好的算法。

比方说,为了辩论的缘故,你将班级作为“工厂”返回。我不知道这是最好的模式,但不是反映你可能会考虑这样的事情:

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 

......但是我又要知道你在做什么。我敢打赌有一个更好的模式。

+0

感谢@john_omalley,我正在使用Spark,并且它的一个API方法(特别是'StructType#add')需要将作为参数的新列/字段的类类型添加到结构中。我正在写一个帮助器函数,它允许我将字符串值转换为适当的Spark等价物。所以**是**,我确实需要类的类型,而不是实例。 – smeeb