2017-06-23 59 views
10

Ví dụ, nếu tôi có lớp dữ liệu sau:Có cách nào để sử dụng giá trị mặc định trên thông số không bắt buộc khi null được chuyển không?

data class Data(
    val name: String = "", 
    val number: Long = 0 
) 

Và chức năng mà có thể trở lại null:

fun newName(): String? {} 

fun newNumber(): Long? {} 

Tôi biết tôi có thể sử dụng sau đây để sử dụng giá trị của các chức năng nếu họ không phải là null:

val newName = newName() 
val newNumber = newNumber() 

val data = Data(
     if (newName != null) newName else "", 
     if (newNumber != null) newNumber else 0 
) 

Nhưng có cách nào để chỉ sử dụng giá trị mặc định được chỉ định trong con cấu trúc của lớp Data khi các giá trị là null?

tôi không thể tìm thấy bất cứ điều gì trong tài liệu, nhưng tôi đã hy vọng một cái gì đó như thế này sẽ làm việc:

val data = Data(newName()?, newNumber()?) 

Nhưng điều đó không biên dịch.

+0

Thay vì 'if (newName! = Null) newName khác" "' bạn chỉ có thể sử dụng 'newName?:" "'. Nó được gọi là toán tử elvis. – Mibac

+0

@Mibac Oh, phải, tôi quên mất điều đó! Chắc chắn gọn gàng hơn, nhưng nó vẫn không sử dụng tham số mặc định được định nghĩa trong hàm tạo lớp. – Bryan

Trả lời

5

Bạn có thể tạo một secondary constructor có sử dụng các giá trị mặc định tương tự khi nhận null:

data class Data(
     val name: String = "", 
     val number: Long = 0 
) { 
    constructor(
      name: String? = null, 
      number: Long? = null 
    ) : this(
      name ?: "", 
      number ?: 0 
    ) 
} 
+0

Ồ, đó là một công việc tuyệt vời! Mặc dù, nó làm cho tôi muốn một cái gì đó như thế này được xây dựng thành ngôn ngữ; nếu chỉ để thoát khỏi bản mẫu. – Bryan

4

constructor thứ chỉ hỗ trợ cho các đặc tính nguyên thủy Nullable. có nghĩa là nó sẽ gây ra 2 nhà xây dựng tương tự nếu tài sản không phải là một loại nguyên thủy, ví dụ:

data class Data(val name: String) { 
    constructor(name: String? = null) : this(name ?: "foo"); 
    // ^--- report constructor signature error     
} 

data class Data(val number: Long = 0) { 
    constructor(number: Long? = null) : this(number ?: 0) 
    //     ^--- No problem since there are 2 constructors generated: 
    //      Data(long number) and Data(java.lang.Long number) 
} 

một cách khác là sử dụng invoke điều hành cho rằng, ví dụ:

data class Data(val name: String) { 
    companion object { 
     operator fun invoke(name: String? = null) = Data(name ?: "") 
    } 
} 

NẾU lớp không phải là lớp dữ liệu, sau đó bạn có thể khởi tạo thuộc tính lười biếng từ tham số, thay vì xác định thuộc tính trên hàm dựng chính, ví dụ:

class Data(name: String? = null, number: Long? = null) { 
    val name = name ?: "" 
    val number = number ?: 0 
} 
Các vấn đề liên quan