Scala ZIO Ref тип данных

У меня есть один класс в Scala с четырьмя параметрами, 2 из которых являются переменными, и я хотел использовать тип данных Ref в Zio для управления доступом к этим переменным, вот мой код:


import zio._

class Rectangle(val width: Int,val height: Int) {

  val x: UIO[Ref[Int]] = Ref.make(0)
  val y: UIO[Ref[Int]] = Ref.make(0)

  def this(x1: Int, y1: Int, width: Int, height: Int) {
    this(width, height)

    for {
      ref <- this.x
      _ <- ref.set(x1)
    } yield ()

    for {
      ref <- this.y
      _ <- ref.set(y1)
    } yield ()
  }

}

чтобы получить доступ к Ref, я написал это:

import zio.console._
import zio._

object AccessRef extends App {
  val myRec = new Rectangle(1, 2, 3, 4)

  override def run(args: List[String]) =
    for {
      rec <- IO.succeed(myRec)
      x <- rec.x
      x1 <- x.get
      _ <- putStrLn(x1.toString)
      _ <-putStrLn(rec.height.toString)
    } yield (0)
}

выход:

0
4

Мне интересно, почему значение ref не может быть обновлено до 1, а не 0?

1 ответ

Решение

val x: UIO[Ref[Int]] = Ref.make(0) не ссылка. Это описание действия, которое возвращает вам ссылку.

Этот код

for {
      ref <- this.x
      _ <- ref.set(x1)
    } yield ()

создает ссылку, устанавливает для нее значение и немедленно удаляет ссылку. Скорее всего, вы хотели бы иметь x а также y быть типа Ref[Int],

Пример:

import zio.console._
import zio._

class Rectangle(val width: Ref[Int], val height: Ref[Int])

object AccessRef extends App {

  override def run(args: List[String]) =
    for {
      recW <- Ref.make(3)
      recH <- Ref.make(5)
      rectangle = new Rectangle(recW, recH)
      oldHeight <- rectangle.height.get
      _ <- putStrLn(s"old value: $oldHeight") //5
      _ <- rectangle.height.set(30)
      newHeight <- rectangle.height.get
      _ <- putStrLn(s"new value: $newHeight") //30
    } yield (0)
}
Другие вопросы по тегам