具有默认值的Scala构造函数

时间:2014-05-30 20:17:35

标签: scala constructor null

我想在下面的商店中拍打读取和/或写入特征。为此,我需要为模式或函数提供默认的类似null的值,然后在运行时检查它们。这是为了允许读,读,写和只写存储。这些特征将定义reader和/或writer,这就是全部。

这看起来像是:

//read only, exception if someone tried to write with it
val rStore = new Store[SomeType](sc, readSchema) with SomeReadTrait
//write only, this would leave inSchema as null-ish so I can check if readfrom is called.
val wStore = new Store[SomeType](sc, outSchema = writeSchema) with SomeWriteTrait
// read/write
val rwStore = new Store[SomeType](sc, readSchema, writeSchema) with SomeReadTrait with SomeWriteTrait
// another way to do read/write
val rwStore = new Store[SomeType](sc, readSchema, writeSchema) with SomeReadWriteTrait

但我无法弄清楚如何在构造函数中创建默认的null-ish值以及内部函数def的默认null-ish值。

我或许可以使用三种抽象类型来处理这个问题,但有没有办法像下面这样做以保持代码DRY。我不在乎是否检查读取器/写入器功能(查看特性是否由特性提供)或模式(查看构造时给出的非null值)或两者兼而有之。

abstract class Store[T](sc: SparkContext, inSchema: Schema = ????, outSchema: Schema = ????){
  /** Reader function that reads from the location into the T and returns it, supplied by a Read trait*/
  def reader: (SparkContext, Schema, String) => T = ????
  /** Writer function, supplied in a Write trait */
  def writer: (SparkContext, Schema, String, T) => ????
  def readFrom(source: String): T = {
    if (reader != ????) reader(sc, inSchema, source) else throw new IllegalArgumentException("Store: readFrom called but there is no reader function has been defined")
  }
  def writeTo(collection: T, dest: String): Unit = {
    if (writer != ????) writer(sc, outSchema, dest, collection) else throw new IllegalArgumentException("Store: writeTo has been called but there is no writer function")
  }
}

2 个答案:

答案 0 :(得分:3)

这是实现你想要的一种奇怪的方式。如果outSchema仅在WriteTrait混入时相关,而inSchema仅在ReadTrait混入时相关,那么为什么它们不属于特征但是其他一些课程的一部分?如果你把它们作为特征的一部分,你可以让编译确保一切正常,而不是抛出IllegalArgumentException

 trait SomeReadTrait[T] {
    val inSchema: Schema
    val context: SparkContext
    def reader(sc: SparkContext, s: Schema, source: String): T = ???
    def readFrom(source: String): T = reader(context, inSchema, source)
 }

 trait SomeWriteTrait[T] {
    val outSchema: Schema
    val context: SparkContext
    def writer(sc: SparkContext, s: Schema, dest: String, collection: T) = ???
    def writeTo(collection: T, dest: String) = writer(context, outSchema, dest, collection)
 }

 trait SomeReadWriteTrait[T] extends SomeReadTrait[T] with SomeWriteTrait[T]

 class ReadStore[T](val context: SparkContext, val inSchema: Schema) extends SomeReadTrait[T]
 class WriteStore[T](val context: SparkContext, val outSchema: Schema) extends SomeWriteTrait[T]
 class ReadWriteStore[T](val context: SparkContext, val inSchema: Schema, val outSchema: Schema) extends SomeReadWriteTrait[T]

这不是你想要的吗?

答案 1 :(得分:0)

借助@ DCKing的帮助,我认为这就是我所需要的。没有抽象类 - 所有特征。有一个根特征定义了readFrom或writeTo的属性和一个方法。扩展特征定义读取或写入的类型以及读取器或写入器。现在为了扩展它,我们只为特定数据类型创建一个新的读或写特征,只写一个受保护的函数。很干。使用String作为各种类型的替代品。

trait RT[T]{
    val sc: String
    val inSchema: String
    protected def reader(sc: String, s: String, source: String): T
    def readFrom(source: String): T = reader(sc, inSchema, source)

}

trait StringReadTrait extends RT[String]{
    protected def reader(sc: String, s: String, source: String): String = {println("StringReadTrait#reader called, sc: "+sc+" s: "+s+" source: "+source); "StringReadTrait#reader"}
}

trait WT[T]{
    val sc: String
    val outSchema: String
    protected def writer(sc: String, s: String, dest: String, collection: String): Unit
    def writeTo(collection: String, dest: String) = writer(sc, outSchema, dest, collection)
}

trait StringWriteTrait extends WT[String]{
    protected def writer(sc: String, s: String, dest: String, collection: String) = {println("writer called, sc: "+sc+" s: "+s+" dest: "+dest+" collection: "+collection)}
}

trait StringReadWriteTrait extends StringReadTrait with StringWriteTrait

class ReadStore(val inSchema: String, val sc: String) extends StringReadTrait
class WriteStore(val outSchema: String, val sc: String) extends StringWriteTrait
class ReadWriteStore(val inSchema: String, val outSchema: String, val sc: String) extends StringReadWriteTrait