2016-09-29 75 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