ZIO STM 没有变异
ZIO STM not mutating
这会打印出 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 ())
我怎样才能(使用最小 结构 更改)让它打印出增加的值?通过一些测试,我知道 TInt
是可靠的。我怀疑,这个问题必须与 Client.stmN
作为 USTM
而不是 反映 潜在的突变有关。
脱衣服 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
现在是返回值 w/in unsafeRun
的一部分。似乎 Client
需要用 USTM
包装起来,以便认真对待其可变性。一般来说,我发现最好不要在各种 classes w/in 组合树之间传播事务。虽然它确实有助于实现良好的 OO 设计,但很难获得所需的可变性。相反,请尝试将所有内容保持在相同 class 并仅使用 stm.T
* 作为状态。
这会打印出 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 ())
我怎样才能(使用最小 结构 更改)让它打印出增加的值?通过一些测试,我知道 TInt
是可靠的。我怀疑,这个问题必须与 Client.stmN
作为 USTM
而不是 反映 潜在的突变有关。
脱衣服 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
现在是返回值 w/in unsafeRun
的一部分。似乎 Client
需要用 USTM
包装起来,以便认真对待其可变性。一般来说,我发现最好不要在各种 classes w/in 组合树之间传播事务。虽然它确实有助于实现良好的 OO 设计,但很难获得所需的可变性。相反,请尝试将所有内容保持在相同 class 并仅使用 stm.T
* 作为状态。