【问题标题】:Any way to achieve something like overriding an operator in kotlin?有什么方法可以实现像在 kotlin 中覆盖运算符之类的东西?
【发布时间】:2018-08-22 17:26:39
【问题描述】:

最近我在 kotlin 中使用列表,并且有以下 sn-p:

a = listOf(1, 2, 3, 4)
println(a[-2])

当然这会导致IndexOutOfBoundsException,所以我认为扩展此功能会很好。所以我认为可以覆盖List 类中的get 运算符:

operator fun <T> List<T>.get(index: Int): T =
        // Here this should call the non-overridden version of
        // get. 
        get(index % size)

我知道扩展只是静态方法,因此不能被覆盖,但是有没有办法可以实现这样的目标?

当然你可以创建另一个函数

fun <T> List<T>.safeGet(index: Int): T = get(index % size)

但我想知道是否有其他方法。

(我知道index % size 是一种非常天真的方式来做我想做的事,但这不是我的问题的重点,并且使代码更小。)

编辑

当我写这个问题时,我认为% 运算符会在右侧为正数时始终返回正数 - 就像在 python 中一样。我在这里保留原始问题只是为了保持一致。

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    你正在尝试一些不可能的事情,因为扩展总是被成员所掩盖,即使@JvmName 也无法拯救你。

    解决方法:使用您的第二种解决方案,或添加一个难看的Unit 参数(看起来像a[x, Unit]),但可以与它自己的get 方法一起存在。

    另一种解决方案:创建自己的 List 实现(推荐)。

    【讨论】:

      【解决方案2】:

      由于get 运算符已在List 中定义,您无法重新定义get(带有一个Int 参数)。 但是,您可以覆盖 invoke 运算符,该运算符未在 List 中定义。

      fun main(args: Array<String>) {
          val a = listOf(1, 2, 3, 4)
          println(a(-2))
      }
      
      // If `index` is negative, `index % size` will be non-positive by the definition of `rem` operator.
      operator fun <T> List<T>.invoke(index: Int): T = if (index >= 0) get(index % size) else get((-index) % (-size))
      

      虽然我认为使用适当的名称为List 创建一个新的扩展方法将是更可取的选择。

      作为旁注,(positive value) % (negative value) 是非负数,(negative value) % (positive value) 是非正数。
      Kotlin 中的% 在以下示例中对应于 Haskell 中的 remhttps://stackoverflow.com/a/28027235/869330

      【讨论】:

      • 好的,旁注让我感到惊讶。我原本没想到。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 2013-09-26
      • 2017-01-17
      • 1970-01-01
      • 2017-11-22
      • 2014-04-20
      相关资源
      最近更新 更多