[英]Implementing scala trait with property that is class object
I have a simple trait我有一个简单的特征
trait SomeTrait {
val sourceData: SourceData
}
SourceData class has constructor parameter p: Array[String]
. SourceData class 具有构造函数参数p: Array[String]
。 Now, when I extend this trait in Object, we must provide implementation for sourceData.现在,当我在 Object 中扩展这个特性时,我们必须为 sourceData 提供实现。
object SomeObject extends SomeTrait {
override val sourceData: SourceData = ???
def main(sysArgs: Array[String]){...}
}
But what if class SourceData needs sysArgs from main method, how can I override sourceData in main method, not in body of SomeObject.但是,如果 class SourceData 需要来自 main 方法的 sysArgs,我如何才能在 main 方法中而不是在 SomeObject 的主体中覆盖 sourceData。 Something like this:像这样:
object SomeObject extends SomeTrait {
def main(sysArgs: Array[String]){
override val sourceData: SourceData = new SourceData(sysArgs)
}
}
I do not want to use var, as val immutability is preferred.我不想使用 var,因为 val 不变性是首选。 And also I want to have trait with no implementation in order to force all sub classes to implement sourceData.而且我还想拥有没有实现的特征,以强制所有子类实现 sourceData。 What other solution I have for this?我还有什么其他解决方案?
You can't avoid mutability in this situation.在这种情况下,您无法避免可变性。 sourceData
must have a value before main
is called, and main
must be able to change that value, so the value must be mutable. sourceData
在调用main
之前必须有一个值,并且main
必须能够更改该值,因此该值必须是可变的。
One option is to make sourceData
a def
(which is a good idea anyway) and have it access a private var
in SomeObject
:一种选择是将sourceData
def
(无论如何这是个好主意)并让它访问SomeObject
中的private var
:
trait SomeTrait {
def sourceData: SourceData
}
object SomeObject extends SomeTrait {
private var mySource: SourceData = ???
def sourceData = mySource
def main(sysArgs: Array[String]) = {
mySource = new SourceData(sysArgs)
}
}
The root problem here is having a top-level object
that needs run-time initialisation.这里的根本问题是有一个需要运行时初始化的顶级object
。 This is required because SomeObject
is a top-level object
that is accessed directly from other parts of the code.这是必需的,因为SomeObject
是一个顶级object
,可以直接从代码的其他部分访问。
The solution to this is dependency injection rather than a global object
.解决方案是依赖注入而不是全局object
。
trait SomeTrait {
def sourceData: SourceData
}
object SomeObject {
case class SomeData(sourceData: SourceData) extends SomeTrait
def main(sysArgs: Array[String]) = {
val theSource = SomeData(SourceData(sysArgs))
// Pass this instance to the rest of the code that needs it
restOfTheProgram(theSource)
}
}
The rest of the code uses the instance of SomeTrait
that is passed to it rather than using SomeObject
directly.代码的SomeTrait
使用传递给它的 SomeTrait 实例,而不是直接使用SomeObject
。
There is no way to do that in Scala. You need to have a class inherit SomeTrait
and instantiate it from the main
method.在 Scala 中没有办法做到这一点。你需要有一个 class 继承SomeTrait
并从main
方法实例化它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.