"恒"案例类中的值

时间:2014-07-24 03:39:05

标签: scala constants case-class

考虑“常量”值:DefaultEncoding。通常我们会将它添加到伴侣对象:

object Strlen {
  val DefaultEncoding = "ISO-8859-1"
  ..
}

但是,我们不得不避免使用伴随对象,因为Strlen必须是一个案例类,以对应重要的现有代码库中的代码结构/约定:

case class Strlen(child: Expression, encoding : Expression) extends UnaryExpression with LengthExpression {

  val DefaultEncoding = "ISO-8859-1"    // This will not be isible in the following constructor

  def this(child: Expression) = this(child, new Literal(DefaultEncoding, StringType))

那么有没有办法在case类中实现DefaultEncoding'常量'的划分?

更新根据wingedsubmariner的建议,我在案例类中尝试了以下内容:

def DefaultEncoding =“ISO-8859-1”

但是它没有编译

[info] Compiling 1 Scala source to /shared/spark-master/sql/catalyst/target/scala-2.10/classes...
[error] /shared/spark-master/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/stringOperations.scala:253: not found: value DefaultEncoding
[error]   def this(child: Expression) = this(child, new Literal(/* StrConstants. */DefaultEncoding, StringType))
[error]       

2 个答案:

答案 0 :(得分:3)

您可以将伴随对象与案例类一起使用。如果在同一个编译单元中声明一个具有相同名称的对象(通常是同一个文件),它将被视为案例类的伴随对象,并具有通常的案例类伴随对象方法,例如, unapply,已添加到其中。

另一种选择是将DefaultEncoding声明为def。因为字段访问总是通过Scala中的访问器完成,所以不会有任何性能损失。

答案 1 :(得分:3)

case class编写自定义伴随对象不会阻止编译器为案例类提供默认的辅助方法。

trait Expression
trait UnaryExpression extends Expression
trait LengthExpression extends Expression

trait Typ
case object StringType extends Typ

case class Literal(val encoding: String, val typ: Typ) extends Expression

case class StrLen(child: Expression, encoding: Expression) extends UnaryExpression with LengthExpression {
  def this(child: Expression) = this(child, new Literal(StrLen.DefaultEncoding, StringType))
}

object StrLen {
  val DefaultEncoding = "ISO-8859-1"
  def apply(child: Expression): StrLen = apply(child, new Literal(StrLen.DefaultEncoding, StringType))
}

case object ExampleExpression extends Expression

println(StrLen(ExampleExpression))
// --> StrLen(ExampleExpression,Literal(ISO-8859-1,StringType))
println(new StrLen(ExampleExpression))
// --> StrLen(ExampleExpression,Literal(ISO-8859-1,StringType))
def isProduct[T <: Product] {}
isProduct[StrLen]

默认apply仍然由编译器提供(并在def apply(child: Expression中使用),StrLen仍在扩展Product,而toString仍然做正确的事情。 自定义构造函数def this(child: Expression)可能是不必要的,因为您可以使用单参数apply