Scala中同类别两个实例间能否传递值?以Pipe类为例
实现Pipe实例间的自动关联:把pipe1的out传入pipe2的in
嘿,这个需求完全可以在类内部实现!你现在手动设置pipe2.in = pipe1.out的方式虽然可行,但确实可以通过类的设计让这个关联更自动化,甚至支持动态更新。下面给你几种不同的方案,你可以根据自己的需求来选:
方案1:构造函数传入上游管道(静态关联)
如果你的管道连接关系是创建时就确定的,不会中途改变,那可以在Pipe类的构造函数里接受一个上游Pipe参数,初始化时直接把上游的out赋值给当前实例的in:
class Pipe(val upstream: Pipe = null) { var vel = 3.4 var V = 300 var a = 10.2 // 有上游就用上游的out,没有就设默认值(这里用0.0,你可以根据需求改) var in = upstream match { case p: Pipe => p.out case _ => 0.0 } var TotV = V + in var out = TotV * a / vel }
使用的时候直接把pipe1传给pipe2的构造函数:
val pipe1 = new Pipe val pipe2 = new Pipe(pipe1)
⚠️ 注意:这种方式的in、TotV、out都是初始化时计算的固定值,如果之后修改了pipe1的vel、V或者a,pipe2的这些值不会自动更新,因为它们只在创建时计算一次。
方案2:用方法动态计算(支持实时更新)
如果希望pipe2的in能实时跟随pipe1的out变化(比如pipe1的属性修改后,pipe2的相关值自动更新),那可以把in、TotV、out改成方法,每次访问时重新计算:
class Pipe(var upstream: Pipe = null) { var vel = 3.4 var V = 300 var a = 10.2 // 动态获取上游的out,没有上游就返回默认值 def in: Double = upstream match { case p: Pipe => p.out case _ => 0.0 } def TotV: Double = V + in def out: Double = TotV * a / vel }
使用的时候:
val pipe1 = new Pipe val pipe2 = new Pipe(pipe1) // 比如修改pipe1的属性 pipe1.V = 400 // 此时访问pipe2.out会自动用pipe1更新后的out值 println(pipe2.out)
这种方式的好处是完全实时,只要上游的属性变化,下游访问相关值时都会用最新的结果。而且你还可以随时切换上游:
val pipe3 = new Pipe() pipe2.upstream = pipe3 // 之后pipe2的in就会用pipe3的out了
方案3:惰性值(折中方案)
如果既想避免每次访问都重新计算,又想在第一次访问时获取最新的上游值,可以用lazy val:
class Pipe(val upstream: Pipe = null) { var vel = 3.4 var V = 300 var a = 10.2 lazy val in = upstream match { case p: Pipe => p.out case _ => 0.0 } lazy val TotV = V + in lazy val out = TotV * a / vel }
这种方式下,in、TotV、out会在第一次被访问时计算,之后就固定下来,除非你重新创建实例。适合那些上游属性不会中途修改的场景。
注意事项
- 避免循环依赖:比如不要让pipe1的上游是pipe2,这样访问
out时会无限递归,导致栈溢出。 - 线程安全:如果是多线程环境下修改
Pipe的属性或者切换上游,可能需要加同步机制,避免出现不一致的结果。
内容的提问来源于stack exchange,提问作者Delta1x
相关产品推荐
相关产品推荐

