【问题标题】:Unable to understand Scala's type inference无法理解 Scala 的类型推断
【发布时间】:2019-04-08 17:57:24
【问题描述】:

我正在经历使用 Scala 学习并发 它有以下一段代码。

package week_parallel.week1.SC_Book

import scala.collection.mutable

object SyncPoolArgs extends App {
  private val tasks = mutable.Queue[() => Unit]()
  object Worker extends Thread {
    setDaemon(true)
    def poll() = tasks.synchronized {
      while (tasks.isEmpty) tasks.wait()
      tasks.dequeue()
    }
    override def run() = while (true) {
      val task = poll()
      task()
    }
  }
  Worker.start()
  def asynchronous(body: =>Unit) = tasks.synchronized {
    tasks.enqueue(() => body)
    tasks.notify()
  }

  def sum(x: Int, y:Int) = {println("USING SUM")
    x+y}

  asynchronous { log("Hello ") }
  asynchronous { log("World!") }
  asynchronous { sum(4,5) }
  Thread.sleep(500)
}

所以,我的问题是,如果我们有不带参数且不返回任何内容的函数类型的任务,为什么tasks.enqueue(() => body) 将 sum 放入队列中,它不应该在 sum 的情况下检查 body 方法签名是否错误.

另外,我特别无法理解tasks.enqueue(() => body) 是如何限制在private val tasks = mutable.Queue[() => Unit]() 类型的?

【问题讨论】:

标签: scala


【解决方案1】:

我想你可能对声明感到困惑

body: => Unit

这意味着bodypass-by-name 类型的Unit 参数。这意味着body 是一个返回Unit 的函数,即body: () => Unit

“按名称传递”表示传递给body 的表达式在需要该值之前不会被计算。当它被评估时,它将返回Unit

由于bodyUnit 类型,所以表达式() => body 具有() => Unit 类型,这是必需的。

在这种情况下,body 的实际值为sum(4,5),即Int 类型,但IntUnit 兼容,因此没有错误。

【讨论】:

  • 按值传递参数还是按名称传递?
  • 这是传名。
  • 对我的错误深表歉意,当然是“按名称传递”。感谢@DmytroMitin 修复了我的错误。
  • @DmytroMitin,我正在查看 Alvin 的教程 alvinalexander.com/scala/fp-book/…,其中他定义了以下 def timer(blockOfCode: => theReturnType),这表示返回类型.. 对此有什么想法吗?
  • @IshanBhatt 您可以根据需要调用类型def timer(blockOfCode: => BlaBlaType)。在某些意义上,=> A() => AUnit => A 类型是相似的。内部方法def foo(body: => A) bodyA 类型,内部方法def bar(body: () => A) body()A 类型,内部方法def baz(body: Unit => A) body(())A 类型。但在 Scala 类型系统中,=> AA 类型的名称参数)、() => AA 类型的零参数函数)、Unit => AUnit 类型的单个参数函数到A) 是不同的。
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多