这将打印出5的不变值。
import zio.stm._
import zio.Console
import zio.Runtime.{default => rt}
class TInt(n: TRef[Int]):
def ++(): USTM[Unit] = n.update(_ + 1)
override def toString: String = n.toString
object TInt:
def make(n: Int): USTM[TInt] = TRef.make(n).map(TInt(_))
class Client:
val stmN: USTM[TInt] = TInt.make(5)
def increment: USTM[Unit] = stmN.flatMap(_.++())
val c = Client()
rt.unsafeRun(for
_ <- c.increment.commit
n <- c.stmN.commit
_ <- Console.printLine(n)
yield ())我如何(w/最小结构更改)让它打印出增量值而不是?通过一些测试,我知道TInt是可靠的。这个问题,我怀疑,必须做w/ Client.stmN是一个USTM,而不是反映潜在的突变。
发布于 2022-03-10 22:19:57
取消stmN: STM[TInt],现在它只是n: Tint,并被作为构造函数参数进行跟踪。这就需要将Client的构造有效地引入到TRef.map中。
import zio.stm._
import zio.Console
import zio.Runtime.{default => rt}
class TInt(n: TRef[Int]):
def ++(): USTM[Unit] = n.update(_ + 1)
override def toString: String = n.toString
object TInt:
def make(n: Int): USTM[TInt] = TRef.make(n).map(TInt(_))
class Client(val n: TInt):
def increment: USTM[Unit] = n.++()
object Client:
def apply(): USTM[Client] = TInt.make(5).map(new Client(_))
rt.unsafeRun(for
c <- Client().commit
_ <- c.increment.commit
_ <- Console.printLine(c.n)
yield ())这样做的效果是,c现在是unsafeRun中返回值w/in的一部分。似乎Client需要包装w/ a USTM,以便认真对待它的易变性。总的来说,我发现最好不要在组合树中的不同类之间分散事务。虽然它确实为一个好的OO设计,但它使它很难获得所需的可更改性。相反,尝试将所有内容保持在同一个类中,只使用stm.T*作为状态。
https://stackoverflow.com/questions/71416020
复制相似问题