5

Giả sử đoạn mã sau:Làm cách nào để chuyển tham số kiểu cho tham chiếu hàm tạo lớp chung?

class ConstructMe<T> {} 
data class Test<T> constructor(var supplier:() -> ConstructMe<T>) {} 

fun main(args: Array<String>) { 
    works<Int>() 
    breaks<Int>() 
} 

fun <T> works() { 
    Test<T>({ ConstructMe<T>() }) // (1) any one class type parameter can be removed like: 
    Test({ ConstructMe<T>() }) // (2) still works (class type inferred by argument type) 
    Test<T>({ ConstructMe() }) // (3) still works (argument type inferred by class type) 
} 

fun <T> breaks() { 
    Test<T>(::ConstructMe) // type interference failed (should probably work like (3); compiler improvement possible?) 
    Test<T>(::ConstructMe<T>) // type interference failed & type argument not allowed (language change necessary?) 
} 

tôi đã chạy vào này bằng cách thông qua các thuộc tính JavaFX (SimpleIntegerProperty, SimpleStringProperty ... và SimpleObjectProperty<T>) vào một constructor của lớp cha chung () -> Property<T> tranh cãi, nơi đi qua ::SimpleIntegerProperty công trình mà không có một vấn đề , trong khi ::SimpleObjectProperty không thành công như mã ví dụ trên.

Có thể cải thiện trình biên dịch tại đây hoặc để cho phép các tham số kiểu truyền vào tham chiếu hàm/hàm không? Thậm chí nó có ý nghĩa khi sử dụng các tham chiếu hàm dựng trên các biểu thức lambda đơn giản ở đây không? Nó có biên dịch khác không?

Trả lời

2

Có, bạn có thể cải thiện trình biên dịch tại đây. Nó có thể suy ra tham số kiểu cho ConstructMe. Xem vấn đề https://youtrack.jetbrains.com/issue/KT-10711.

Đối với chức năng không tiếp thị nội bộ (trong trường hợp này nó là hàm tạo của Kiểm tra), không có sự khác biệt giữa lambda và tham chiếu có thể gọi đến hàm tạo. Đối với cả hai trường hợp trình biên dịch tạo ra lớp ẩn danh có phương thức invoke tạo ra một thể hiện của ConstructMe.

Nhưng tham chiếu có thể gọi là thuận tiện hơn lambda trong trường hợp hàm tạo có nhiều tham số.

Các vấn đề liên quan