可以这样做吗?
final case class C[A] (v: A) {
def this() = this(true)
}
当使用给定的构造函数构造时,C自动为C [Boolean]。这个版本没有编译,但感觉它应该以某种方式可行,特别是因为以下似乎工作:
final case class C[A] (v: A = true)
我想要一些Java互操作性,所以我尽量避免使用默认值。我认为我可以通过在伴随对象中使用工厂方法来实现这一点,但它可以直接完成吗?由于C是一个案例类,工厂方法有点乱,恕我直言。
答案 0 :(得分:3)
有什么问题
object C{
def apply() = C(true)
}
这样你就可以使用伴侣对象?在Java中,这可能是C$.apply()
没有?
答案 1 :(得分:2)
我怀疑伴侣对象中的工厂方法是你能做的最好的(正如wheaties
建议的那样)。我们可以编译它,但是以牺牲愚蠢为代价。例如:
final case class C[A] (v: A) {
def this() = this("Hello".asInstanceOf[A]) // Compiles, thanks to type erasure
}
val c = new C[Int]() // Still compiles, despite the fact that "Hello" is not an Int
println(c) // C(Hello)
c.v + 1 // Compiles, but throws a ClassCastException at run-time
基本问题是类参数是在类级而不是构造函数级指定的,因此所有构造函数都必须使用相同的类型参数。另一方面,方法可以采用类型参数,因此工厂方法没有问题。此外,工厂方法的Java Interop并不是那么糟糕。你可以这样做:
// C.scala
final case class C[A] (v: A)
object C {
def apply(): C[Boolean] = C(true)
}
// Test.java
public class Test {
public C c = C.apply();
}
scala编译器创建静态方法来简化Java互操作,因此通常不需要使用C$
。