Kotlin:通过并使用2参数函数?

eri*_*cky 0 kotlin

我正在尝试在Kotlin中学习函数式编程,并且很难使这段代码工作:

import java.util.*

fun caseName(br: String, c: Int): String {
  if (c == 0) {
    return br.toLowerCase()
    } else {
    return br.toUpperCase()
    }
}
fun mapIt(ns: ArrayList<String>, f: (String, Int) -> String): List<String> {
  val coll: List<String> = ns.map {it -> f(it, _)}
  return coll
}

fun main(args: Array<String>) {
  val names = arrayListOf("Joe", "Bill", "Murrary")
  val cased = mapIt(names, (::caseName)(_, 0))
  println(cased.first())
}
Run Code Online (Sandbox Code Playgroud)

mapIt在映射列表时如何识别案例标志?

谢谢!

编辑:上面的案例是以下的简化版本,它不起作用......

data class Borrower(val name: String, val maxBooks: Int) {
    companion object {

        fun getName(br: Borrower, c: Int): String {
          if (c == 0) {
            return br.name.toLowerCase()
            } else {
            return br.name.toUpperCase()
            }
        }

        fun findBorrower(n: String, brs: ArrayList<Borrower>, f: (Borrower) -> String): Borrower? {
            val coll: List<Borrower> = brs.filter { it -> f(it) == n }
            if (coll.isEmpty()) {
                return null
            } else return coll.first()
        }
    }
}

fun main(args: Array<String>) {
    val br1 = Borrower(name = "Borrower1", maxBooks = 1)
    val br2 = Borrower(name = "Borrower2", maxBooks = 2)
    val br3 = Borrower(name = "Borrower3", maxBooks = 3)
    val br4 = Borrower(name = "borrower4", maxBooks = 4)
    val br5 = Borrower(name = "BORROWER5", maxBooks = 5)
    val brs1 = arrayListOf(br1, br2, br3, br4, br5)

    val c = Borrower.findBorrower("borrower3", brs1, {Borrower.Companion::getName(it, 0)})
    println(c)
}
Run Code Online (Sandbox Code Playgroud)

Oli*_*rth 5

这里有几个问题:

  1. 你的目标在这里是矛盾的 - 你想要mapIt一个2-arg函数,但它看起来也像你正在尝试执行部分应用caseName,这当然会导致1-arg函数.

  2. 下划线不会在Kotlin中做到你想象的(看起来你可能来自Scala背景?).

看起来你想要这样的东西:

// f is a *single*-arg function
fun mapIt(ns: ArrayList<String>, f: (String) -> String): List<String> {
    return ns.map(f)
}

fun main(args: Array<String>) {
    val names = arrayListOf("Joe", "Bill", "Murrary")
    val cased = mapIt(names, { caseName(it, 0) })  // Partial application
    println(cased.first())
}
Run Code Online (Sandbox Code Playgroud)

或者像这样:

// f is a two-arg function
fun mapIt(ns: ArrayList<String>, f: (String, Int) -> String): List<String> {
    return ns.map { f(it, 0) }
}

fun main(args: Array<String>) {
    val names = arrayListOf("Joe", "Bill", "Murrary")
    val cased = mapIt(names, ::caseName)
    println(cased.first())
}
Run Code Online (Sandbox Code Playgroud)