2017-08-14 30 views
0

在Kotlin中,修改List.get的行爲的慣用方式是什麼?調用get(-1)返回列表中的最後一個元素?修改Kotlin中的List.get行爲

我試圖擴展:

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

但可根據需要它沒有表現,而我得到了警告

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

我認爲你的意思'返回此[IF(指數<0)大小+指數別人指數]' –

+0

這有什麼錯'list.last'?清楚地說明你在做什麼,並且不需要基於索引的訪問。 –

回答

2

既然你不能隱藏與擴展方法的成員方法,唯一可行的選擇是按照描述的方式擁有一個覆蓋功能的子類。

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

但是,您應該考慮此代碼的未來用戶。它混淆了這裏發生的事情。 list[index]的含義基於index的值而改變,並且在list和/或index未預先知曉的地方這將不明顯。考慮這個簡單的例子:

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

如果today是2和daysAgo爲7,則此方法要麼拋出一個異常(如果timeline是一個普通的列表)或從未來返回的東西(如果timelineNegativelyIndexableList) 。

如果您確實需要此功能,請考慮不要將它與get合併。添加一個新方法:

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

除此之外,您可以創建代理來提供循環視圖。例如''cyclic(list)[ - 1]' –

+1

而不是'asReversed()'的開銷,你可以使用'get(size - index)' –

+0

你可以:那正是'asReversed()'所做的(請參閱ReversedViews.kt)。我會使用'asReversed()',因爲它更具可讀性,稍微減少了錯誤的機會,增加了一個明智的例外,並且更加習慣。 –