2017-08-14 1 views
0

In Kotlin, was ist die idiomatische Möglichkeit, das Verhalten von List.get so zu ändern, dass Aufruf get(-1) das letzte Element in der Liste zurückgibt?Ändern List.get Verhalten in Kotlin

habe ich versucht, eine Erweiterung:

operator fun <T> List<T>.get(index: Int): T { 
    return this[if (index < 0) size + index else index] 
} 

Aber es verhält sich nicht wie gewünscht, und ich bekam die Warnung

scratch.kts:3:26: warning: extension is shadowed by a member: public abstract operator fun get(index: Int): T 
operator fun <T> List<T>.get(index: Int): T { 
         ^
+1

Ich glaube, Sie bedeuten 'return this [if (Index <0) Größe + Index sonst index]' –

+0

Was mit 'list.last' falsch? Gibt eindeutig an, was Sie tun und benötigt keinen indexbasierten Zugriff. –

Antwort

2

Da Sie kein Mitglied Verfahren mit einem Verlängerungsverfahren verstecken Die einzige Option, die funktioniert, wäre eine Unterklasse, die die Funktionalität in der beschriebenen Weise überschreibt.

class NegativelyIndexableList<T> : ArrayList<T>() { 
    override fun get(index: Int): T = 
    if (index < 0) super.get(size + index) else super.get(index) 
} 

Allerdings sollten Sie die zukünftigen Benutzer dieses Codes berücksichtigen. Es verschleiert, was hier vor sich geht. Die Bedeutung von list[index] ändert sich basierend auf dem Wert index, und dies wird nicht offensichtlich an Orten, wo list und/oder index nicht im Voraus bekannt sind. Betrachten Sie dieses triviale Beispiel:

fun getValueFromAFewDaysAgo(timeline: List<Day>, today: Int, daysAgo: Int) = 
    timeline[today - daysAgo] 

Wenn today 2 und daysAgo 7, dann wird diese Methode entweder eine Ausnahme aus (wenn timeline eine reguläre Liste ist) oder bei etwas aus der Zukunft (wenn timeline ist ein NegativelyIndexableList) .

Wenn Sie diese Funktion wirklich benötigen, sollten Sie sie nicht mit get zusammenführen. Fügen Sie eine neue Methode:

fun getFromEnd(index: Int) = asReversed()[index] 
+1

Darüber hinaus können Sie einen Proxy erstellen, um eine zyklische Ansicht bereitzustellen. zB: 'cyclic (list) [- 1]' –

+1

Anstelle des Overheads von 'asReversed()' könntest du 'get (size - index)' verwenden –

+0

Du könntest: das ist genau das, was 'asReversed()' tut (siehe ReversedViews.kt). Ich würde mit 'asReversed()' gehen, da es besser lesbar ist, die Wahrscheinlichkeit von Fehlern um eins verringert, eine sinnvolle Ausnahme hinzufügt und idiomatischer ist. –

Verwandte Themen