我面临着隐含参数和tratis的有趣问题。
我有一个抽象类Parent
隐含地接受一个整数和另外两个参数:
abstract class Parent(a: Int)(implicit str: String, map: Map[String,String]) {/*...*/}
以及将与ClassTrait
混合并使用含义的特征Parent
:
trait ClassTrait {
val str: String
val map: Map[String,String]
def doSth() = str.length
}
所以现在我想这样做( withnout 关键字abstract
):
class Child(a: Int)(implicit str: String, map: Map[String,String]) extends Parent(a) with ClassTrait {
def doSth2 = doSth * 10
}
我应该使用什么语法将隐式参数映射到特征值?编译器返回此错误:
foo.scala:10: error: class Child needs to be abstract, since:
value map in trait ClassTrait of type Map[String,String] is not defined
value str in trait ClassTrait of type String is not defined
class Child(a: Int)(implicit str: String, map: Map[String,String]) extends Parent(a) with ClassTrait {
^
one error found
在复杂的例子中,我在特征中使用隐式参数,但由于特征不能有任何参数(没有构造函数),我需要再次声明使用的含义。
感谢您的帮助。
答案 0 :(得分:3)
尝试
class Child(a: Int)(implicit val str: String, map: Map[String,String]) extends Parent(a) with ClassTrait {
def doSth2 = doSth * 10
}
(参见我添加的val
)
或使用case class
。然后他们将成为领域。
替代方法可能是不使它们隐式,并在伴随对象中使用apply方法,该方法需要使用implicits来设置它们。但是你仍然需要创建它们,你的当前代码在技术上只是将它们视为构造函数args。
答案 1 :(得分:2)
您可以使用val关键字将字参数提升为字段:
abstract class Parent(a: Int)(implicit val str: String, val map: Map[String,String]) {/*...*/}
注意“val str”和“val map”而不仅仅是“str”和“map”。通过这种方式,它们将成为适当的只读成员,并为您的特征的抽象成员提供实现。