2011-04-30 237 views
5

返回一个懒惰的VAL我有一个看起来像这样的功能:在斯卡拉

package org.thimblr.io 
import java.io._ 
object Local { 
    def streamer(path: String) =() => new FileReader(path) 
} 

这基本上管理是我想做的事,这是返回打开从文件流功能,当它被称为。因此,客户端代码可以做到这一点:

val planStreamSource = Local.streamer("/home/someuser/.plan") 
//...passes the function on to somewhere else 
val planStream = planStreamSource() 
val firstByte = planStream.read 
//can now read from planStream 

但我真的很想是返回一个懒惰的VAL一旦它引用了从文件流,像这样:

val planStream = Local.streamer("/home/someuser/.plan") 
//...passes the val on to somewhere else, without opening the file for reading yet 
val firstByte=planStream.read 
//...such that planStream was only just opened to allow the read 

是否有可能做这样的事情,返回一个懒惰的val,以便客户端代码可以将它视为一个值而不是一个函数?

+1

为什么你不只是做'高清流光(路径:字符串)=新的FileReader(路径)'和'懒惰VAL planStream = Local.streamer( “/家/ SomeUser的/。计划”)'? – 2011-04-30 17:26:33

+0

,因为我想提供这个val到代码中的其他地方,与不是来自文件的流交换,而是来自套接字或其他东西。如果我将planStream作为参数传递给另一个函数,那么我不希望该文件在此时打开。我希望在客户端代码实际准备好开始使用流时(在try finally块中)打开它。 – traffichazard 2011-04-30 19:20:16

+0

试图把斯卡拉当作懒惰评估的语言来对待它的谷物。您可以使用lazy'val'和by-name参数来创建延迟评估值容器,但我不推荐将其作为系统范围的编程风格。 – 2011-05-01 16:32:10

回答

15

你不能“返回一个懒惰VAL” - 客户端代码必须声明为懒惰。如果你不希望强制客户端来声明一个懒惰的VAL,你可以返回的包装来代替:

class LazyWrapper[T](wrp: => T) { 
    lazy val wrapped: T = wrp 
} 

object LazyWrapper { 
    implicit def unboxLazy[T](wrapper: LazyWrapper[T]): T = wrapper.wrapped 
} 

然后:

def streamer(path: String) = new LazyWrapper(new FileReader(path)) 

,你可以进一步向前equalshashCode等。如果您需要这些,请联系LazyWrapper中的包装对象。

+0

我喜欢这个。我是新来的Scala,为了实验的缘故,我试图坚持一种功能风格,所以我试图在没有类包装的情况下做。但是你的建议可能是这样做的最简单的方法。 – traffichazard 2011-04-30 19:26:54