我试图在接受可变数量参数的trait中声明函数,并且在实现trait期间,我将扩展参数数量。如何在Scala中完成
我期望提供如下代码。
trait Column {
def rule
}
case object FirstColumn extends Column{
def rule(s: String) : String
}
case object SecondColumn extends Column{
def rule(s1: String, s2: String) : String
}
我尝试使用Strings *,但是不允许我在实现过程中扩展参数数量。我知道可以使用多种方法来解决此问题,但我特别希望拥有上述签名供我的团队编写函数。
答案 0 :(得分:2)
这主要是针对我对这个问题的评论。这个答案可以使您尽可能地接近Scala所需要的内容,但这也说明了为什么做自己的工作可能不是一个好主意。
您可以表达(接近)您想要的类型,但是我不确定您打算获得什么。首先,如果要采用其他arglist类型,则Column
必须是通用的。
trait Column[-A] {
def rule(arg: A): String
}
然后我们可以将您的case对象实现为对此的适当参数化的子类。
case object FirstColumn extends Column[String] {
def rule(arg: String): String =
"stub implementation"
}
case object SecondColumn extends Column[(String, String)] {
def rule(arg: (String, String)): String =
"stub implementation"
}
请注意,FirstColumn
和SecondColumn
不会从相同的Column[A]
继承,因为它们没有实现相同的方法。我们可以使它们具有共同的类型,但是……不是一种非常有用的方式。
一个选择是找到Column[String]
和Column[(String, String)]
的公共超类型,这(因为自变量是自变量)类似于找到String
和{{1}的公共子类型。 }。最接近的常见子类型是... (String, String)
。除非您仅打算将Null
传递到null
,否则这无济于事。
相反,我们可以使用存在性。
rule
现在,我们已经丢失了所有类型信息。您可以访问 val foo: Column[_] = FirstColumn
val bar: Column[_] = SecondColumn
插槽并可以打印它,但是您不能调用它,因为我们不知道需要传递什么。您必须进行强制转换才能将其恢复为可用格式。
我在这里要说的是,是的,这是可行的,但是一旦丢失了尽可能多的类型信息,就没有什么意义了。类型系统正确地告诉我们foo.rule
和foo
实际上没有什么共同之处,只是名为bar
的方法的 existence 存在……论据。从类型理论的角度来看,很难做到比这更有趣。