最近初始化一个val [英] Initializing a val lately
问题描述
是否有可能在Scala中仅使用val:
class MyClass {
private val myVal1: MyClass2 // ..... ?????这里应该是什么?
$ b $ def myMethod1(param1:Int)= {
myVal1 = new MyClass2(param1)
// ....
//一些代码....
$ b $ p
$ b 这个想法是我不能初始化 myVal1
,因为它的构造函数的参数是未知的,我必须在 myMethod1
中做这件事。 myVal1
应该是可见的,并且应该是不可改变的。
不允许有可变状态。
所以有可能吗?
解决方案这是不可能的,但有一些方法(除了使用param1作为构造函数参数外)
- 将
var
更改为一个选项
; setter myMethod1
返回同一个类的新实例, Option
设置为该值。 b $ b - 使用
var
创建一个单独的可变 Builder
类,并在稍后将其变为不可变的类,收集所有数据
- 如果您正在处理正向或循环引用,请考虑使用 call-by-name 和
懒惰val
s(示例1 ,示例2 )
更新:示例1:
class MyClass(val myVal1:Option [Int]){
def myMethod1(param1:Int ):MyClass = {
new MyClass(Some(param1))
}
}
MyClass {
def apply()= new MyClass无)
def apply(i:Int)= new MyClass(Some(i))
}
这个模式被 immutable.Queue 举例。
更新:3(循环引用)的示例:
// ref ...按名称调用
class MyClass(val id:Int,ref:=> MyClass){
lazy val myVal1 = ref
$ b $ override def toString:String = s$ id - > $ {myVal1.id}
}
可以这样使用:
val a:MyClass = new MyClass(1,b)
val b:MyClass = new MyClass(2,a)
println(a)
println(b)
更新:3(正向引用)的示例: p>
class MyClass2(val id:Int)
// ref ...按名称调用
class MyClass(val id:Int,ref:=> MyClass2){
lazy val myVal1 = ref
override def toString:String = s$ id - > $ {myVal1 .id}
与
一起使用
val a = new MyClass(1,x)
println(a.id)//您可以使用a.id,但还不是懒惰val
val x = new MyClass2(10)
println(a)
Is it possible to do that in Scala using only val:
class MyClass {
private val myVal1: MyClass2 //.....????? what should be here?
def myMethod1(param1: Int) = {
myVal1 = new MyClass2(param1)
//....
// some code....
}
}
The idea is that I can't initialize myVal1
immediately since the argument for its constructor is unknown yet and I have to do that in myMethod1
. myVal1
should be visible withing a class and should be immutable.
No mutable state allowed.
So is it possible?
解决方案 This is not possible, but there are some ways (in addition to using param1 as a constructor parameter)
- Change the
var
into an Option
; the setter myMethod1
returns a new instance of the same class with the Option
set to the value.
- Create a separate mutable
Builder
class with a var
, and turn it into an immutable one later, when all data has been collected
- If you are dealing with forward or cyclic references, consider using call-by-name and
lazy val
s (example 1, example 2)
Update: Example for 1:
class MyClass(val myVal1: Option[Int]) {
def myMethod1(param1: Int): MyClass = {
new MyClass(Some(param1))
}
}
object MyClass {
def apply() = new MyClass(None)
def apply(i: Int) = new MyClass(Some(i))
}
This pattern is used by immutable.Queue for example.
Update: Example for 3 (cyclic reference):
// ref ... call by name
class MyClass(val id: Int, ref: => MyClass) {
lazy val myVal1 = ref
override def toString: String = s"$id -> ${myVal1.id}"
}
to be used like this:
val a: MyClass = new MyClass(1, b)
val b: MyClass = new MyClass(2, a)
println(a)
println(b)
Update: Example for 3 (forward reference):
class MyClass2(val id: Int)
// ref ... call by name
class MyClass(val id: Int, ref: => MyClass2) {
lazy val myVal1 = ref
override def toString: String = s"$id -> ${myVal1.id}"
}
to be used with
val a = new MyClass(1, x)
println(a.id) // You can use a.id, but not yet the lazy val
val x = new MyClass2(10)
println(a)
这篇关于最近初始化一个val的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!