2012-02-29 6 views
30

Chính xác những gì mà tuyên bố tham số phương pháp có nghĩa là:loại tham số chức năng và =>

def myFunc(param: => Int) = param 

nghĩa của => trong định nghĩa trên là gì?

+19

Sử dụng [Symbol Hound] (http://symbolhound.com) trong tương lai. –

+0

có thể trùng lặp của [Scala - What '=> SomeType' có nghĩa là gì?] (Http: // stackoverflow.com/questions/7225308/scala-what-does-sometype-means) –

+0

Không biết làm thế nào tôi không tìm thấy nó ... Hãy suy nghĩ tôi nên thay đổi kính của tôi ... :) – PrimosK

Trả lời

51

Đây được gọi là pass-by-name. Điều đó có nghĩa là bạn đang chuyển một hàm trả về Int nhưng chủ yếu được sử dụng để thực hiện đánh giá lười biếng các tham số. Nó có phần tương tự như:

def myFunc(param:() => Int) = param 

Dưới đây là ví dụ. Hãy xem xét một chức năng answer trở về một số Int giá trị:

def answer = { println("answer"); 40 } 

Và hai chức năng, người ta dùng Int và một tham Intbởi tên:

def eagerEval(x: Int) = { println("eager"); x; } 
def lazyEval(x: => Int) = { println("lazy"); x; } 

Bây giờ thực hiện cả trong số họ sử dụng answer:

eagerEval(answer + 2) 
> answer 
> eager 

lazyEval(answer + 2) 
> lazy 
> answer 

Trường hợp đầu tiên là obvi ous: trước khi gọi eagerEval()answer được đánh giá và in "answer" chuỗi. Trường hợp thứ hai thú vị hơn nhiều. Chúng tôi đang thực sự chuyển một hàm đến lazyEval(). lazyEval in đầu tiên "lazy" và đánh giá tham số x (thực tế, gọi hàm x được truyền làm tham số).

cũng Xem

+0

Giải thích tuyệt vời !!! +1 – PrimosK

+2

Cụm từ bạn muốn là "tên theo từng chữ" —không phải "giá trị theo giá trị". Đi qua giá trị là một cái gì đó khá khác nhau; đó là những gì Java làm với nguyên thủy. – Destin

+4

Tôi nghĩ rằng bạn có nghĩa là "gọi theo tên", không phải "tên theo từng lần" hoặc "chuyển qua giá trị" (xem thông số ngôn ngữ 4.6.1) –

10

Chỉ cần chắc chắn rằng có một câu trả lời có sử dụng thuật ngữ thích hợp: Scala Language Specification sử dụng thuật ngữ gọi bằng tên:

Loại tham số giá trị có thể được đặt trước bởi =>, ví dụ: x: => T. Loại tham số như vậy là kiểu phương thức không tham số => T. Điều này chỉ ra rằng đối số tương ứng không được đánh giá tại điểm ứng dụng chức năng, nhưng thay vào đó, được đánh giá ở mỗi lần sử dụng trong hàm. Tức là, đối số là được đánh giá sử dụng gọi từng tên.

- Mục 4.6.1 của Scala Language Specification

6

Để thêm vào câu trả lời Tomasz Nurkiewicz của trên, sự khác biệt giữa tôi gặp phải() => Int và => Int được rằng thứ hai cho phép gọi với khối trần :

scala> def myfunc(f :() => Int) = println("Evaluated: " + f) 
myfunc: (f:() => Int)Unit 

scala> def myfunc2(f : => Int) = println("Evaluated: " + f) 
myfunc2: (f: => Int)Unit 

scala> myfunc({1}) 
<console>:9: error: type mismatch; 
found : Int(1) 
required:() => Int 
       myfunc({1}) 
       ^

scala> myfunc2({1}) 
Evaluated: 1