2016-11-21 6 views
5

Kotlin hat default arguments for function and constructor parameters. Nun habe ich eine FunktionWie propagieren Standardargumente zwischen Funktionen in Kotlin?

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

und ich es nennen will aus verschiedenen Orten, sondern auch die Möglichkeit behalten, um nicht auf den Argumente übergeben und stattdessen den Standardwert verwenden.

ich weiß, kann ich die Standardargumente in den Aufruf von Funktionen

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) 
} 

aber jetzt mein Standard-Parameter in foo erklären ist sinnlos, da es sich immer overwriten und ich habe die Standardargumente in allen Aufruf von Funktionen dupliziert. Das ist nicht sehr trocken.

Gibt es eine bessere Möglichkeit, die Standardargumente zu propagieren?

Antwort

1

Beantworten Sie meine eigene Frage wie von the guidelines gefördert.


Was Sie tun können, ist es, die Parameter in den Anruffunktionen wie NULL-Werte zulässt und null als Standard-Argument deklarieren:

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) 
} 

Wenden Sie dann eine der elvis operator zu verwenden, Standardwerte, wenn null bereitgestellt wird.

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

Wenn Sie sich mit einer Klasse statt einer Funktion zu tun, können Sie die Eigenschaft des Konstrukteurs ziehen und dort den Standardwert zuweisen:

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

, sagen, wenn Ihre Klasse ist ein data class und Sie die Eigenschaften in der primären Konstruktor haben, können Sie eine Factory-Methode deklarieren die Standardwerte zu handhaben:

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

Warum die downvote? –

2

Statt drei Spaß haben ctions mit den gleichen Standardargumente:

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

eine Wrapper-Klasse erstellen, die in den Argumenten entgegennimmt, und haben die Funktionen ohne Parameter:

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

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

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

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

Wenn Sie die gleichen Argumente mehrere Funktionen haben nehmen (mit der gleiche Standardwerte), dann ist das ein Code-Geruch, der darauf hindeutet, dass diese Parameter eng miteinander verwandt sind und innerhalb ihrer eigenen Klasse leben sollten.

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) 
} 

Wenn foo und/oder foo2, foo3 nur ihre Argumente verwenden, dann weiter Refactoring würde foo und foo2 in die FooArgs Klasse bewegen, was zu einer ähnlichen Lösung the answer by @nhaarman

Verwandte Themen