Nói rằng tôi muốn khai báo một kiểu dữ liệu đại số đơn giản cho các danh sách số nguyên:Trong Kotlin, làm thế nào để bạn khai báo một lớp dữ liệu với các tham số hàm tạo không?
sealed class IntList
data class Cons(val head: Int, val tail: IntList): IntList()
data class Nil() : IntList()
Tuy nhiên, kết quả khai cuối cùng trong một lỗi
lớp dữ liệu phải có ít nhất một tham số nhà xây dựng chính
- Tại sao hạn chế này có mặt? Nhìn vào tài liệu, có vẻ như không có lý do kỹ thuật tốt để yêu cầu các nhà xây dựng lớp dữ liệu không phải là vô giá trị.
Có thể thể hiện các nhà xây dựng vô giá trị mà không cần phải viết nhiều mã soạn sẵn không? Nếu tôi thay đổi tuyên bố cuối cùng để một cái gì đó giống như
sealed class Nil() : IntList()
sau đó tôi mất việc triển khai miễn
hashCode()
vàequals()
đi kèm miễn phí vớidata class
tờ khai.
EDIT
Alex Filatov đã đưa ra một giải pháp ngắn đẹp dưới đây. Rõ ràng, bạn không bao giờ cần nhiều hơn một thể hiện của Nil
, vì vậy chúng tôi chỉ có thể xác định một đối tượng singleton
object Nil : IntList()
Tuy nhiên, những gì chúng ta sẽ làm gì nếu danh sách của chúng tôi đã được tham số hóa bởi một tham số kiểu? Đó là, bây giờ hai dòng đầu tiên của định nghĩa của chúng tôi sẽ là
sealed class List<A>
data class Cons<A>(val head: A, val tail: List<A>): List<A>()
Chúng ta không thể khai báo một đối tượng đa hình singleton Nil
mà xuất phát từ List<A>
cho bất kỳ A
, vì chúng ta phải cung cấp một loại bê tông cho A
tại thời điểm tờ khai. Các giải pháp (lấy từ this post) là tuyên bố A
như một tham số kiểu hiệp biến và tuyên bố Nil
như một subtype của List<Nothing>
như sau:
sealed class List<out A>
data class Cons<A>(val head: A, val tail: List<A>): List<A>()
object Nil : List<Nothing>()
Điều này cho phép chúng tôi viết
val xs: List<Int> = Cons(1, Cons(2, Nil))
val ys: List<Char> = Cons('a', Cons('b', Nil))
liên quan: https://stackoverflow.com/questions/37873995/how-to-create-empty-constructor-for-data-class-in-kotlin-android Nhưng có vẻ như không phù hợp với hoàn cảnh của bạn. – BakaWaii
Ngoài ra, "_Lưu ý rằng các thuộc tính không được khai báo trong hàm dựng chính không tham gia kiểm tra bình đẳng và tính toán hashcode._" – BakaWaii
@UlrikRasmussen Tại sao bạn cần 'hashCode()' và 'equals()' nếu lớp không nên chứa bất kỳ trường nào? –