代码之家  ›  专栏  ›  技术社区  ›  softshipper

描述计算

  •  0
  • softshipper  · 技术社区  · 6 年前

    我有下面的代码,我想知道,为什么变量 number 计算两次:

    import cats.effect.IO
    
    import scala.util.Random
    
    object Main {
    
      private val number: IO[Int] =
        IO(Random.between(3, 300))
    
      def main(args: Array[String]): Unit = {
    
    
        number
          .flatMap { e =>
            println(e);
            number
          }.flatMap { e =>
          println(e);
          IO.unit
        }.unsafeRunSync()
      }
    
    }
    

    程序打印两个不同的数字,尽管这个数字是一个赋值。我知道这里,我描述的是计算而不是执行,在宇宙的尽头,我运行程序。

    问题是,为什么它会打印出两个不同的数字?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Micha Wiedenmann Lieven Keersmaekers    6 年前

    两者之间有区别

    private val number: IO[Int] = IO(Random.nextInt())
    

    private val number2: Int = Random.nextInt()
    

    number 计算时计算随机数的值。当多次计算此类型的值时 IO (也称为此计算)多次运行,产生多个不同的随机数。

    反之 number2 当被评估只是一个数字。

    它与lambda的区别非常相似( val lambda = () => Random.nextInt() )和一个价值( val value = Random.nextInt() )

        2
  •  2
  •   Mario Galic    6 年前

    IO 有点像下面的场景

    final case class SuspendedComputation[T](f: () => T) {
      def run: T = f()
    }
    
    val v = SuspendedComputation(Random.nextInt)
    v.run
    v.run
    

    输出类似于

    v: SuspendedComputation[Int] = SuspendedComputation(<function>
    res2: Int = -1062309211
    res3: Int = 765640585
    

    注意如何 SuspendedComputation 内部存储计算为 () => Random.nextInt 然后使用 run 计算的实际评估方法 f .

    同样地, IO.apply 按名称接受参数 : => A 并最终构建 Delay 对象,该对象将字段中未计算的计算存储为 () => A 然后使用 unsafeRunSync 实际评估计算。

    推荐文章