2011-08-05 27 views
12

Sau đây là cả hai cách để tạo Luồng số nguyên:Khi nào một luồng cần phải lười?

val s: Stream[Int] = 1 #:: s.map(_ + 1) 

def makeStream = { 
    val s: Stream[Int] = 1 #:: s.map(_ + 1) 
    s 
} 

Đầu tiên là tiền phạt; Tuy nhiên phương pháp makeStream sẽ không biên dịch:

error: forward reference extends over definition of value s 
    val s: Stream[Int] = 1 #:: s.map(_ + 1) 
          ^

Nó chỉ biên dịch nếu chúng ta làm s một lazy val. Tại sao nó cần phải là một lazy val trong một phương pháp, nhưng không phải ở bên ngoài?

Trả lời

16

Bên trong một lớp học, một phân tách định nghĩa val thành một phương thức "getter" tham chiếu đến một trường lớp ẩn. Các phương thức "getter" này có thể tự tham chiếu (hoặc đúng hơn, trình khởi tạo lớp có thể tham chiếu đến "getter") vì đây là ngữ nghĩa của các phương thức Java. Lưu ý rằng định nghĩa "bên ngoài" của bạn là val s thực sự được bao bọc trong một lớp ẩn bởi REPL (đây là cách REPL phá vỡ giới hạn mà không thể khai báo ở mức cao nhất) val.

Bên trong một phương pháp, định nghĩa val không dịch ngược thành một phương thức "getter", nhưng thay vào đó là bytecode cần thiết để tạo ra một giá trị trên ngăn xếp. Mặt khác, lazy val luôn yêu cầu phương thức "getter", có thể tự tham chiếu.

Các vấn đề liên quan