2009-09-08 42 views
6

Sự hiểu biết của tôi về toán tử Groovy .& là nó chuyển đổi cuộc gọi phương thức thành đóng. Do đó nó có vẻ như đoạn mã sau (có thể được chạy trong Groovy console) nên làm việc:Phương thức gọi là đóng

class Foo { 
    def method(def param) { 
    param + 10 
    } 
} 

def invokeClosure = {Closure closure -> 
    return closure.call() 
} 

def f = new Foo() 
invokeClosure f.&method(6) 

Tất nhiên nếu tôi thay đổi dòng cuối cùng để

invokeClosure {f.method(6)} 

nó hoạt động tốt, nhưng những gì xảy ra với sự hiểu biết của tôi về nhà điều hành .&?

Cảm ơn, Don

Trả lời

8

Khi chuyển đổi một phương pháp để đóng cửa sử dụng . & ký hiệu bạn bỏ qua các tham số. f. Phương pháp & (6) giống như gọi f.method (6) sẽ trả về 16, vì vậy trong ví dụ của bạn, bạn đang chuyển 16 vào invokeClosure và không phải là đóng. Gây ra các ngoại lệ sau đây kể từ khi lớp Integer không có một phương pháp gọi:

ngoại lệ ném: Không có chữ ký của phương pháp: java.lang.Integer.call()

Dưới đây qua một con trỏ phương pháp f.method vào invokeClosure và sẽ là cách bạn thường sử dụng. &.

class Foo { 
    def method(def param) { 
    param + 10 
    } 
} 

def invokeClosure = {Closure closure -> 
    return closure.call(6) // can leave off .call 
} 

def f = new Foo() 
invokeClosure f.&method 

Như bạn chỉ ra sau đây sẽ làm việc:

invokeClosure {f.method(6)} 

Đó là bởi vì bạn đang đi qua một kết thúc mà sẽ đưa không có tham số vì vậy đó là lý do tại sao closure.call() hoạt động trong trường hợp đó.

+1

Thực ra, nói đúng là tôi nghĩ '{f.method (6)}' là một đóng trong đó có một tham số trong khi '{-> f.method (6)}' là một đóng mà không có tham số. Câu trả lời tuyệt vời mặc dù, cảm ơn! –

1

Sử dụng invokeClosure f.&method.curry(6) để thay thế. Đây là một đóng có thể được gọi mà không có tham số

0

Ví dụ trên cũng có thể được mở rộng để lấy tham số làm đối số vào invokeClosure. Điều đó sẽ cho bạn kết quả và cú pháp dự kiến.

class Foo { 
    def method(def param) { 
    param + 10 
    } 
} 

def invokeClosure = {Closure closure, def parameter -> 
    return closure.call(parameter) 
} 

def f = new Foo() 
invokeClosure f.&method, 6 
Các vấn đề liên quan