为什么需要一个return语句才能正确评估while语句?

Sco*_*Coy 4 scala

为什么需要一个return语句才能正确评估while语句?以下声明允许

import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.io.BufferedReader
import java.io.InputStreamReader

trait Closeable {
  def close ()
}

trait ManagedCloseable extends Closeable {
  def use (code: () => Unit) {
    try {
      code()
    }
    finally {
      this.close()
    }
  }
}

class CloseableInputStream (stream: InputStream)
extends InputStream with ManagedCloseable {
  def read = stream.read
}

object autoclose extends App {
  implicit def inputStreamToClosable (stream: InputStream):
    CloseableInputStream = new CloseableInputStream(stream)

  override
  def main (args: Array[String]) {
    val test = new FileInputStream(new File("test.txt"))

    test use {
      val reader = new BufferedReader(new InputStreamReader(test))

      var input: String = reader.readLine

      while (input != null) {
        println(input)
        input = reader.readLine
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这会从scalac产生以下错误:

autoclose.scala:40: error: type mismatch;
 found   : Unit
 required: () => Unit
      while (input != null) {
      ^
one error found
Run Code Online (Sandbox Code Playgroud)

它似乎试图将块use作为内联语句而不是lambda来处理,但我不确定为什么.return一段时间后添加 缓解错误:

test use {
  val reader = new BufferedReader(new InputStreamReader(test))

  var input: String = reader.readLine

  while (input != null) {
    println(input)
    input = reader.readLine
  }

  return
}
Run Code Online (Sandbox Code Playgroud)

应用程序按预期运行.有谁能形容我到底发生了什么?这好像应该是一个bug.它在许多版本的Scala中一直存在(测试2.8.0,2.9.0,2.9.1)

ped*_*rla 8

那是因为它use被声明为() => Unit,所以编译器期望你给出的块use返回满足这个签名的东西.

看来你想要的是把整个块变成一个名字参数,这样就改成def use (code : () => Unit)def use (code : => Unit).