2016-11-21 14 views
5

Kotlin có default arguments for function and constructor parameters. Bây giờ, tôi có một chức năngLàm thế nào để truyền các đối số mặc định giữa các hàm trong Kotlin?

fun foo(bar: String = "ABC", baz: Int = 42) {} 

và tôi muốn gọi nó từ những nơi khác nhau nhưng cũng giữ lại khả năng không chuyển qua đối số và thay vào đó sử dụng giá trị mặc định.

Tôi biết, tôi có thể tuyên bố đối số mặc định trong các chức năng gọi

fun foo2(bar: String = "ABC", baz: Int = 42) { 
    // do stuff 
    foo(bar, baz) 
} 

fun foo3(bar: String = "ABC", baz: Int = 42) { 
    // do other stuff 
    foo(bar, baz) 
} 

nhưng bây giờ thông số mặc định của tôi trong foo là vô nghĩa vì nó luôn overwriten và tôi đã nhân đôi các đối số mặc định trong tất cả các chức năng gọi điện thoại. Đó không phải là rất khô.

Có cách nào tốt hơn để truyền bá các đối số mặc định không?

Trả lời

1

Trả lời câu hỏi của riêng tôi như được khuyến khích bởi the guidelines.


gì bạn có thể làm, là tuyên bố các thông số trong chức năng gọi điện thoại như nullable và sử dụng null như là đối số mặc định:

fun foo2(bar: String? = null: Int? = null) { 
    // do stuff 
    foo(bar, baz) 
} 

fun foo3(bar: String? = null, baz: Int? = null) { 
    // do other stuff 
    foo(bar, baz) 
} 

Sau đó, sử dụng một trong những elvis operator sử dụng giá trị mặc định, khi null được cung cấp.

fun foo(bar: String? = null, baz: Int? = null) { 
    val realBar = bar ?: "ABC" 
    val realBaz = baz ?: 42 
} 

Nếu bạn đang làm việc với một lớp thay vì một chức năng, bạn có thể kéo ra thành tài sản của các nhà xây dựng và gán giá trị mặc định đó:

class Foo(bar: String? = null, baz: Int? = null) { 
    val bar = bar ?: "ABC" 
    val baz = baz ?: 42 
} 

Ngoài ra, nói rằng nếu lớp học của bạn là một data class và bạn muốn có các thuộc tính trong các nhà xây dựng chính, bạn có thể khai báo một phương pháp nhà máy để xử lý các giá trị mặc định:

class Foo(val bar: String, baz: Int) { 
    companion object { 
     fun create(bar: String? = null, baz: Int? = null) = Foo(bar ?: "ABC", baz ?: 42) 
    } 
} 
+0

Tại sao downvote? –

2

Thay vì có ba niềm vui ctions với các đối số mặc định giống nhau:

fun foo(bar: String = "ABC", baz: Int = 42) 
fun foo2(bar: String = "ABC", baz: Int = 42) 
fun foo3(bar: String = "ABC", baz: Int = 42) 

Tạo một lớp wrapper mà mất trong các đối số, và có các chức năng không có tham số:

class Foo(val bar: String = "ABC", val baz: Int = 42) { 

    fun foo() { /* ... */ } 

    fun foo2() { 
    // ... 
    foo() 
    } 

    fun foo3() { 
    // ... 
    foo() 
    } 
} 
0

Nếu bạn có nhiều chức năng dùng những lập luận tương tự (với cùng các giá trị mặc định), thì đó là một đoạn mã gợi ý rằng các tham số đó có liên quan chặt chẽ và phải sống bên trong lớp riêng của chúng.

data class FooArgs(val bar: String = "ABC", val baz: Int = 42) 

fun foo(args: FooArgs = FooArgs()) { /* ... */} 

fun foo2(args: FooArgs = FooArgs()) { 
    ... 
    foo(args) 
} 

fun foo3(args: FooArgs = FooArgs()) { 
    ... 
    foo(args) 
} 

Nếu foo và/hoặc foo2, foo3 chỉ sử dụng lập luận của họ, sau đó sắp xếp thêm sẽ di chuyển foofoo2 vào lớp FooArgs, dẫn đến một giải pháp tương tự để the answer by @nhaarman

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