2016-07-11 18 views
2

Ich versuche, eine Erweiterungsfunktion für eine veränderbare Eigenschaft festzulegen, damit ich die Eigenschaft in der Erweiterungsfunktion neu zuweisen kann. Ich wollte wissen, ob es möglich ist.Kotlin-Erweiterungsfunktion für veränderbare Eigenschaft

Meine Ziele sind Date Erweiterungen für den einfachen Zugriff zu machen. Zum Beispiel:

fun Date.addDays(nrOfDays: Int): Date { 
    val cal = Calendar.getInstance() 
    cal.time = this 
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays) 
    return cal.time 
} 

Diese Funktion fügt Anzahl von Tagen zu einem Datum eines Calendar Objekt. Das Problem ist jedes Mal, wenn ich ein neues Datum zurückgeben muss, was bei jeder Verwendung dieser Funktion verwirrend sein kann.

Was ich habe versucht:

fun KMutableProperty0<Date>.addDays(nrOfDays: Int) { 
    val cal = Calendar.getInstance() 
    cal.time = this.get() 
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays) 
    this.set(cal.time) 
} 

Leider kann dies nicht auf ein Date Objekt verwendet werden.

Ist es möglich, dies zu tun?

+0

Ist dies tatsächlich kompilieren (entweder Ihre Snippets)? Das 'time'-Feld eines' Calendar'-Objekts hat den Typ 'int', sieht aber so aus, als würden Sie ihm einen' Date'-Wert zuweisen. Und dann gibst du 'cal.time' wieder als' Date' zurück, während es ein 'int' ist. –

+0

@ MarcinKoziński, beide haben keine Fehler auf meiner Seite, und 'cal.time' ist' java.util.Date'. – hotkey

+0

@ MarcinKoziński Ja beide kompilieren, aber die zweite kann nicht auf einem Date-Objekt verwendet werden. 'cal.time' gibt ein' Date' zurück –

Antwort

1

Leider können Sie keine Erweiterung auf einer Mitgliedseigenschaft definieren und in Kotlin 1.0.3 fließend aufrufen.

kann Ihre Erweiterung neu geschrieben werden, wie dies funktioniert:

fun <T> KMutableProperty1<T, Date>.addDays(receiver: T, nrOfDays: Int) { 
    val cal = Calendar.getInstance() 
    cal.time = this.get(receiver) 
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays) 
    this.set(receiver, cal.time) 
} 

mit folgenden Nutzung:

class C(var date: Date) { ... } 
val c = C(someDate()) 

C::date.addDays(c, 123) 

Mit bound callable references (likely supported in Kotlin 1.1) dies mit folgenden Syntax möglich sein wird:

c::date.addDays(123) 

Wie @ MarcinKoziński schon sagt, können Sie auch Ihre Date Objekte mutieren, ohne dass die Eigenschaft Neuzuweisung:

fun Date.addDays(nrOfDays: Int) { 
    val cal = Calendar.getInstance() 
    cal.time = this 
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays) 
    this.time = cal.timeInMillis 
} 

mit Nutzung:

class C(var date: Date) 
val c = C(someDate()) 

c.date.addDays(123) 

Mit dieser Lösung müssen Sie die Verweise auf das Date Objekt steuern, welche ist mutiert. Diese Lösung eignet sich gut für veränderbare Objekte, obwohl sie nicht für eine Eigenschaft geeignet ist, die unveränderliche Objekte speichert.

+0

Die erste Option sieht gut aus, ich kann sie leider nicht benutzen. Es hat einen Fehlertyp des Empfängers. Es erscheint auch nicht in der automatischen Vervollständigung. Ich verwende das Datum in einer Funktion, also erstelle ich eine Variable, die ein Datum ist und versuche, die Erweiterungsfunktion aufzurufen. Irgendeine Ahnung, was ich falsch mache? –

+0

@KevinvanMierlo, haben Sie die Erweiterungssignatur in 'fun geändert KMutableProperty1 .addDays (...)'? Funktioniert gut für mich, der Anruf ist 'C :: date.addDDays (c, 123)'. – hotkey

+0

Ja, ich habe die Signatur geändert. Habe etwas anderes falsch gemacht, es funktioniert jetzt. Es ist nicht ideal, aber es ist etwas. Danke für die Antwort! –

3

Anstatt ein neues Date zurückzukehren und zu versuchen, um Ihr Eigentum zu aktualisieren, können Sie einfach die Date mutieren, die Ihre Immobilie bereits gilt:

fun Date.addDays(nrOfDays: Int) { 
    val cal = Calendar.getInstance() 
    cal.time = this 
    cal.add(Calendar.DAY_OF_YEAR, nrOfDays) 
    this.time = cal.timeInMillis 
} 
+0

Ich kann nicht glauben, dass ich das nicht getan habe .. Das würde mein ganzes Problem beheben, danke! –

+0

Während dies mein Problem behebt, beantwortet die Antwort von @hotkey meine Frage. Also muss ich seine Antwort als die richtige akzeptieren. Aber vielen Dank für diese Antwort, das behebt viele Probleme, die ich hatte. –