为什么需要一个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)
那是因为它use被声明为() => Unit,所以编译器期望你给出的块use返回满足这个签名的东西.
看来你想要的是把整个块变成一个名字参数,这样就改成def use (code : () => Unit)了def use (code : => Unit).