возвращение ленивого Вала в Скала - PullRequest
5 голосов
/ 30 апреля 2011

У меня есть функция, которая выглядит следующим образом:

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

Можно ли сделать что-то подобное, вернуть ленивое значение, чтобы клиентский код мог воспринимать его как значение, а не как функцию?

1 Ответ

15 голосов
/ 30 апреля 2011

Вы не можете «вернуть ленивый код» - код клиента должен объявить его как ленивый. Если вы не хотите заставлять клиента объявлять отложенное значение, вы можете вернуть оболочку:

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))

Вы можете дополнительно переслать equals, hashCode и т. Д. В обернутый объект в LazyWrapper, если они вам нужны.

...