如何使数组具有对象类型的方法?

时间:2018-09-05 19:04:42

标签: kotlin

这个问题是要找出语言是否有可能,而不是特定的问题或案例。

我仍在学习Kotlin的动力学和功能方面。


有没有办法解决这个问题?

for (item in myList) item.someMethod()

变成这样:

myList.all().someMethod()

2 个答案:

答案 0 :(得分:0)

给出:

00002902-0000-1000-8000-00805f9b34fb

您可以执行以下操作:

data class MyObj(val v: String) {
    fun someMethod() {
        println(v)
    }
}

val myList = listOf(MyObj("A"), MyObj("B"), MyObj("C"))

for (item in myList) item.someMethod()

这是对特定类型列表的简单扩展功能。

如果您需要诸如动态调度之类的东西,那将是不可能的。

但是也许您需要的是Composite设计模式,其中容器和元素都实现相同的接口。像这样:

fun List<MyObj>.someMethod() {
    for (e in this) {
        e.someMethod()
    }
}

fun List<MyObj>.all() = this

将类似地工作:

interface SomeInterface {
    fun someMethod()
}

class MyList(val elements: List<MyObj>) : SomeInterface {
    override fun someMethod() {
        for (e in elements) {
            e.someMethod()
        }
    }
}

data class MyObj(val v: String) : SomeInterface{
    override fun someMethod() {
        println(v)
    }
}

此模式在元素集合和单个元素之间提供了很好的约定。

答案 1 :(得分:0)

只需保持简单即可。

myList.forEach { it.someMethod() }
// or
myList.forEach(Item::someMethod)

扩展功能也是可以的,但是可能已经太多了(至少将其缩小到您的类型):

fun List<Item>.someMethod() = forEach { it.someMethod() }

或者,如果您希望依赖于特定的接收者来访问该方法,则还可以在该特定的类型内声明扩展功能。因此,给定类型为MyObj的扩展函数如下:

class MyObj {
  val funnyItems = mutableListOf<Item>()
  val usefulItems = mutableListOf<Item>()
  val whateverItems = mutableListOf<Item>()

  fun List<Item>.someMethod() = forEach { it.someMethod() }
}

它只有在您具有适当的接收器的情况下才可以调用。因此,在类MyObj中添加一个函数,如下所示:

fun callingSomeMethod() = funnyItems.someMethod() // no problem

,但不能在MyObj之外使用。例如。考虑不在main内的MyObj方法:

fun main(args: Array<String>) {
  listOf(MyObj())
    .forEach {
    // the following will not work... it is not accessible without appropriate receiver
    // it.funnyItems.someMethod() // doesn't compile...
      with(it) {
        // 'this' is now MyObj which is the required receiver in addition to List<Item>, so the following works:
        this.funnyItems.someMethod()
      }
    }
}