我正在嘗試Ref[F, A]在 2 個并發流之間共享一個。下面是實際場景的簡化示例。
class Container[F[_]](implicit F: Sync[F]) {
private val counter = Ref[F].of(0)
def incrementBy2 = counter.flatMap(c => c.update(i => i 2))
def printCounter = counter.flatMap(c => c.get.flatMap(i => F.delay(println(i))))
}
在主函式中,
object MyApp extends IOApp {
def run(args: List[String]): IO[ExitCode] = {
val s = for {
container <- Ref[IO].of(new Container[IO]())
} yield {
val incrementBy2 = Stream.repeatEval(
container.get
.flatTap(c => c.incrementBy2)
.flatMap(c => container.update(_ => c))
)
.metered(2.second)
.interruptScope
val printStream = Stream.repeatEval(
container.get
.flatMap(_.printCounter)
)
.metered(1.seconds)
incrementBy2.concurrently(printStream)
}
Stream.eval(s)
.flatten
.compile
.drain
.as(ExitCode.Success)
}
}
所做的更新在incrementBy2中不可見printStream。我怎樣才能解決這個問題?對于理解此代碼中的錯誤,我將不勝感激。
謝謝
uj5u.com熱心網友回復:
自類定義以來,您的代碼已損壞,您甚至沒有更新相同的代碼Ref
請記住,要點IO是對計算的描述,因此Ref[F].of(0)回傳一個程式,在評估時將創建一個 new Ref,對其呼叫 multipleflatMaps將導致Refs創建多個。
此外,您沒有以正確的方式進行無標簽決賽(有些人可能會認為即使是正確的方式也不值得:https ://alexn.org/blog/2022/04/18/scala-oop-design-sample / )
這就是我撰寫代碼的方式:
trait Counter {
def incrementBy2: IO[Unit]
def printCounter: IO[Unit]
}
object Counter {
val inMemory: IO[Counter] =
IO.ref(0).map { ref =>
new Counter {
override final val incrementBy2: IO[Unit] =
ref.update(c => c 2)
override final val printCounter: IO[Unit] =
ref.get.flatMap(IO.println)
}
}
}
object Program {
def run(counter: Counter): Stream[IO, Unit] =
Stream
.repeatEval(counter.printCounter)
.metered(1.second)
.concurrently(
Stream.repeatEval(counter.incrementBy2).metered(2.seconds)
).interruptAfter(10.seconds)
}
object Main extends IOApp.Simple {
override final val run: IO[Unit] =
Stream
.eval(Counter.inMemory)
.flatMap(Program.run)
.compile
.drain
}
PS:我實際上不會有
printCounter,但getCounter會在Program
您可以看到這里運行的代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/459006.html
上一篇:使用JDBC(Sqlserver)查詢tempview
下一篇:繪制3d函式失敗
