Các bài viết wikipedia cho Scala thậm chí trả lời những gì từ khóa lazy
làm:
Sử dụng từ khóa lười biếng trì hoãn việc khởi tạo một giá trị cho đến khi giá trị này được sử dụng.
Ngoài ra, những gì bạn có trong mẫu mã này với q : => Parser[U]
là thông số theo từng tên. Một tham số được khai báo theo cách này vẫn chưa được đánh giá, cho đến khi bạn đánh giá nó một cách rõ ràng ở đâu đó trong phương thức của bạn.
Dưới đây là một ví dụ từ REPL scala về cách các thông số cuộc gọi-by-tên làm việc:
scala> def f(p: => Int, eval : Boolean) = if (eval) println(p)
f: (p: => Int, eval: Boolean)Unit
scala> f(3, true)
3
scala> f(3/0, false)
scala> f(3/0, true)
java.lang.ArithmeticException:/by zero
at $anonfun$1.apply$mcI$sp(<console>:9)
...
Như bạn có thể thấy, 3/0
không được đánh giá ở tất cả trong cuộc gọi thứ hai. Kết hợp giá trị lười với tham số gọi tên như kết quả ở trên theo nghĩa sau: tham số q
không được đánh giá ngay lập tức khi gọi phương thức. Thay vào đó, nó được gán cho giá trị lười biếng p
, cũng không được đánh giá ngay lập tức. Chỉ sau này, khi sử dụng p
điều này dẫn đến việc đánh giá là q
. Nhưng, như p
là một thông số val
, q
sẽ chỉ được đánh giá sau khi và kết quả được lưu trữ trong p
để sử dụng lại sau này trong vòng lặp.
Bạn có thể dễ dàng nhìn thấy trong repl, rằng việc đánh giá nhiều có thể xảy ra trường hợp:
scala> def g(p: => Int) = println(p + p)
g: (p: => Int)Unit
scala> def calc = { println("evaluating") ; 10 }
calc: Int
scala> g(calc)
evaluating
evaluating
20
Bạn đã đặt bất kỳ nỗ lực trong việc cố gắng tìm hiểu chính mình? Đó là một phần của ngôn ngữ Scala và tìm kiếm trên internet sẽ tiết lộ đủ số lần truy cập vào 'scala lazy'. – ziggystar
@ziggystar: Tôi đã thực hiện 2-3 tìm kiếm trên Google và không thể tìm thấy bất kỳ điều gì hữu ích. Lập luận lười biếng đã được đề cập trên một số yêu cầu tính năng Scala, nhưng không có lời giải thích nào mà tôi có thể hiểu được đã được đưa ra ở đó. –
@ziggystar: Yêu cầu tính năng có tại đây: https://issues.scala-lang.org/browse/SI-240. Ngoài ra, tìm kiếm 'scala lazy' hoặc thậm chí' scala lazy argument' dường như không mang lại nhiều thông tin hữu ích bởi vì bạn hầu như sẽ nhận được kết quả về những thứ cơ bản hơn như lazy val và call-by-name. –