Tôi bối rối hơn nhà xây dựng SAM, tôi có lớp này Java:Không thể thay thế SAM-constructor với lambda khi số đầu tiên là một lớp học với một phương pháp
public class TestSam<T> {
public void observe(ZeroMethods zero, Observer<T> observer) {
}
public void observe(OneMethod one, Observer<T> observer) {
}
public void observe(TwoMethods two, Observer<T> observer) {
}
public interface Observer<T> {
void onChanged(@Nullable T t);
}
public interface ZeroMethods {
}
public interface OneMethod {
First getFirst();
}
public interface TwoMethods {
First getFirst();
Second getSecond();
}
public interface First {
}
public interface Second {
}
}
Và mã Kotlin này:
fun testSam(
test: TestSam<String>,
zero: TestSam.ZeroMethods,
one: TestSam.OneMethod,
two: TestSam.TwoMethods
) {
test.observe(zero) { println("onChanged $it") } // 1. compiles
test.observe(zero, TestSam.Observer { println("onChanged $it") }) // 2. Redundant SAM-constructor
test.observe(one) { println("onChanged $it") } // 3. doesn't compile
test.observe({ one.first }) { println("onChanged $it") } // 4. compiles
test.observe(one, TestSam.Observer { println("onChanged $it") }) // 5. compiles
test.observe(two) { println("onChanged $it") } // 6. compiles
test.observe(two, TestSam.Observer { println("onChanged $it") }) // 7. Redundant SAM-constructor
}
Thỏa thuận ở đây là gì? Tại sao Kotlin không thể tìm ra 3. (và cung cấp biến thể đặc biệt 4.), nhưng xử lý tất cả các trường hợp khác?
Lý do cho mã này là LiveData<T>.observe(LifecycleOwner owner, Observer<T> observer)
phương pháp trong Android, nơi LifecycleOwner
có một phương pháp getLifecycle()
.
Bạn có thể thêm liên kết vào mã nguồn trình biên dịch không? (hoặc một đặc điểm kỹ thuật mà điều này được giải thích?) (Hoặc bạn có tìm thấy câu trả lời bằng cách thử nó không?) – Marco13
Tôi nghĩ rằng nó không thực sự tài liệu, chỉ cần cố gắng ra bản thân mình. Để cụ thể hơn, tốt hơn là hỏi các nhà phát triển Kotlin. Một trong số họ nói với tôi rằng có một vấn đề trong trình theo dõi lỗi cho điều đó. – Beholder
Ồ, tôi nghĩ tôi hiểu điều đó. Vì vậy, vấn đề là 'OneMethod' và 'LifecycleOwner' của Android là các giao diện SAM. Thật tệ, đó chỉ là tình cờ, thực sự, bởi vì tôi nghi ngờ 'LifecycleOwner' được sử dụng theo cách' Runnable' được sử dụng, chúng ta sẽ không bao giờ định nghĩa các lớp ẩn danh cho nó trong Java, thay vào đó giao diện được thực hiện bởi 'AppCompatActivity' lớp cơ sở. – arekolek