scala的代码块 和 无参代码的区别

在Scala中,创建线程时发现`run`方法未执行,问题源于对`=> Unit`和`() => Unit`的理解。`=> Unit`表示代码块,不能直接调用,而`() => Unit`则表示无参方法。将代码块传给`=> Unit`会导致无法执行,而`() => Unit`能传递给`=> Unit`,暗示了可能的类型关系,这与Scala的函数逆变和协变概念相关。
摘要由CSDN通过智能技术生成

前言

最近在创建线程的时候写了如下代码,然后发现线程内的 run 方法总是无法执行:

object MyThread {
  def thread(body:  => Unit): Thread = {
    val thread = new Thread {
      override def run(): Unit = body
    }
    thread.start()
    thread
  }
  
  def main(args: Array[String]): Unit = {
    println("main thread start")
    val t = thread(() => {
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} start ...")
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} is running ...")
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} new thread stop ...")
    })
    
    t.join()
    println("main thread end")
  }
}

输出:

main thread start
main thread end

Process finished with exit code 0

经过分析,主要是 thread 方法 body 参数的定义,使用,和传参使用不正确

=> Unit

=> Unit 类型代表的不是方法,代表的是个代码块,给该类型传参的时候虽然可以传递方法,但是由于该类型不能调用,所以参数也无法执行。但是传递一个代码块就可以。

  def thread(body:  => Unit): Thread = {
    val thread = new Thread {
      override def run(): Unit = body  // 不能写成 body(),因为 => Unit 不支持
    }
    thread.start()
    thread
  }

在上面的示例中,body 是无法调用的。虽然可以传递一个 () => Unit 类型的方法给body, 但是由于无法调用,在这里也没有什么用。但是如果直接传递一个代码块,就没有影响:

thread({
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} start ...")
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} is running ...")
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} new thread stop ...")
    })

() => Unit

() => Unit 相比前者好理解一些,就是一个无参方法。

  def thread(body:  () => Unit): Thread = {
    val thread = new Thread {
      override def run(): Unit = body() // 这里可以调用
    }
    thread.start()
    thread
  }
  def main(args: Array[String]): Unit = {
    println("main thread start")
    val t = thread(() => { // 这路传递的是匿名方法,不再是代码块
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} start ...")
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} is running ...")
      Thread.sleep(1000)
      println(s"${Thread.currentThread().getName} new thread stop ...")
    })

    t.join()
    println("main thread end")
  }

需要注意的事这里并不能传递代码块。所以 () => Unit 可以传递给 => Unit 。 反过来不能,所以可以推断出 => Unit 也许是 () => Unit 的父类(实际上可能不是这样,这个可能和scala中函数的逆变和协变有关)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值