我正在尝试解决“Scala for the Impatient”一书中提出的问题,该书要求将java的BufferedInputStream作为特征实现。这是我的实现,
trait Buffering {
this:InputStream =>
private[this] val bis = {
new JavaBufferedInputStream(this)
}
override def read = bis.read
override def read(byte:Array[Byte], off:Int, len:Int) = bis.read(byte, off, len)
override def available = bis.available
override def close() {
bis.close
}
override def skip(n:Long) = bis.skip(n)
}
def main(args:Array[String]) {
val bfis = new FileInputStream(new File("foo.txt")) with Buffering
println(bfis.read)
bfis.close
}
但是这给了我一个java stackoverflow错误,那么它有什么问题呢?谢谢!
答案 0 :(得分:4)
看起来你正在获得一个堆栈溢出,你不期望它。解决这些问题的关键是查看堆栈跟踪的重复循环。它通常指向重复分配帧的内容。在这里它将显示类似的东西:
at C.Buffering$class.read(C.scala:12)
at C.C$$anon$1.read(C.scala:23)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at C.Buffering$class.read(C.scala:12)
at C.C$$anon$1.read(C.scala:23)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
at C.Buffering$class.read(C.scala:12)
因此,从下到上阅读,看起来read(byte, ...)
正在呼叫bis.read(byte, ...)
正在呼叫BufferedInputStream.read
,然后再次呼叫您的read(byte, ...)
。
new BufferedInputStream(this)
似乎在底层read
上调用了InputStream
,但由于基础this
是您的对象,然后委托bis
调用我们有无限的递归。
我猜测作者希望您使用abstract override
可堆叠修改模式,您可以使用super
来引用正确的read
方法。
答案 1 :(得分:0)
也许这就是答案。可能是我理解的。
trait Buffering extends InputStream{
abstract override def read()=
{
println("Hello");
super.read()
}
}
val t = new ByteArrayInputStream("hello".getBytes()) with Buffering
答案 2 :(得分:0)
我一直在经历" Scala for the Impatient"。以下是我在第10章中对练习8的解决方案:
import java.io._
object BufferedInputStream extends App {
trait Buffering {
this: FileInputStream =>
val br = new BufferedInputStream(this)
}
def bufferedReader(f: String): Unit = {
val fis = new FileInputStream(f) with Buffering
var c = 0
var blen = 8192
var len = 0
var b = new Array[Byte](blen)
while (fis.br.available > 0) {
if (fis.br.available > blen) len = blen
else len = fis.br.available
c = fis.br.read(b, 0, len)
if (c == -1) return
print((for (i <- 0 to (c - 1)) yield b(i).toChar).mkString)
}
fis.br.close
fis.close
}
bufferedReader("webpagexample")
}