2017-08-14 53 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()',因为它更具可读性,稍微减少了错误的机会,增加了一个明智的例外,并且更加习惯。 –