考虑“常量”值: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]
答案 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
。