2014-10-22 47 views
22

Hãy xem xét các lớp Java sau:biểu thức Lambda trong Kotlin

public class SomeClass { 
    public interface Something { 
     void doSomething(); 
    } 

    public void call(Something something) {} 
} 

Trong Kotlin, tôi có thể sử dụng một biểu thức lambda như sau:

SomeClass().call { 
    // do something 
} 

Nhưng nếu tôi xác định các phương pháp sau đây trong Kotlin (sử dụng cùng một giao diện):

fun call(something: Something) {} 

Sau đó cuộc gọi này:

call { 
    // do something 
} 

Sẽ tạo ra lỗi không khớp loại. Tại sao?

Trả lời

25

Kotlin chỉ hỗ trợ chuyển đổi SAM cho các phương pháp Java, vì Kotlin chính nó có loại chức năng. Thông thường, các chức năng của Kotlin nên dùng () -> Unit thay vì Something. Nếu bạn thực sự cần nó để có Something, bạn có thể sử dụng một constructor SAM:

call(Something { /* do something */ }) 

Bất kỳ loại SAM (giao diện Java với một phương pháp trừu tượng) tự động được như một hàm constructor có thể chuyển đổi một lambda để dụ nó.

+4

Quyết định đó có vẻ lạ đối với tôi. Hãy xem xét 'Danh sách <(T) -> Đơn vị>' vs 'Danh sách >'. Cái thứ hai mang nhiều thông tin hơn. May mắn thay có một cách giải quyết khác: chúng ta có thể sử dụng mã java một cách tự do trong các dự án kotlin. – Yaroslav

+0

Mặc dù không có nhiều cách sử dụng giải pháp đó: ( – Yaroslav

+3

Các loại chức năng được đặt tên là một câu chuyện khác. Và chúng sẽ được hỗ trợ trong phiên bản tiếp theo của Kotlin –

8

Kotlin yêu cầu cuộc gọi đó cần giao diện something.

() -> Kotlin.Unit 

Không thỏa mãn yêu cầu về loại.

Bạn có thể làm điều này

call (object : Something { 
    override fun doSomething() { 
     println("Passing an interface to call in kotlin!") 
    } 
})