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

问题描述 投票:1回答:2

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

我还在学习Kotlin的动态性和功能性。


有没有办法扭转这个:

for (item in myList) item.someMethod()

变成这样的东西:

myList.all().someMethod()

kotlin
2个回答
0
投票

鉴于:

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()

你可以这样做:

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)
    }
}

将类似地工作:

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

myList.someMethod()

这种模式在元素集合和单个元素之间提供了一个很好的契约。


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()
      }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.