【问题标题】:Get name of function argument in higher-order function在高阶函数中获取函数参数的名称
【发布时间】:2018-07-27 01:34:11
【问题描述】:

Kotlin 好像不支持获取本地函数等,请看下面的例子:

fun <T> MutableList<T>.filterOnCondition(condition: (T) -> Boolean): MutableList<T>
{ 
    // For the printline, trying to get the function name, 
    // which in this case is passedAsCondition
    println(condition.reflect()!!.instanceParameter!!.name)
}

fun passedAsCondition (number: Int, multipleOf : Int): Boolean
{
    return number % multipleOf == 0
}

numbers.filterOnCondition { passedAsCondition(it, 5) }

Kotlin 返回此错误,因为它还没有被映射出来:

“kotlin.reflect.jvm.internal.KotlinReflectionInternalError: 内省局部函数、lambda、匿名函数和局部函数 Kotlin 反射尚不完全支持变量"

(https://github.com/JetBrains/kotlin/blob/master/core/reflection.jvm/src/kotlin/reflect/jvm/internal/EmptyContainerForLocal.kt#L41)

但是,这肯定可以通过 Java 实现,不是吗?

【问题讨论】:

  • 我可以写Arrays.asList(5, 6, 10, 13, 15, 24).stream().filter(x -&gt; x % 5 == 0).forEachOrdered(System.out::println); - 不知道你在问什么...关于传递一个函数来过滤?
  • 我正在尝试获取传递给 filterOnCondition 的函数的名称。对于 println(),我希望看到 passAsCondition 返回。
  • @Lander,您正在反思 lambda。 passedAsCondition 在 lambda 主体中。

标签: java android reflection kotlin introspection


【解决方案1】:

这是一个匿名函数,所以它的名字是&lt;anonymous&gt;:

val x: (Int) -> Boolean = { passedAsCondition(it, 5) }
println(x.reflect()?.name) //prints <anonymous>

当您有一个 lambda { passedAsCondition(it, 5) } 时,您希望反射如何在这里工作? passedAsCondition 是在 lambda 内部进行的一个简单调用,但您在一个未命名的匿名 lambda 上调用 reflect,它没有名称。

普通函数可以与当然有名字的方法引用一起使用:

fun x(a: Int): Boolean {
    passedAsCondition(a, 5)
    return true
}
println(::x.name) //gives x

作为结果,利用适当的反射,以下工作:

fun main(args: Array<String>) {
    mutableListOf(1).filterOnCondition(::passedAsCondition)
}


fun <T> MutableList<T>.filterOnCondition(
    condition: KFunction2<@ParameterName(name = "number") Int, @ParameterName(name = "multipleOf") Int, Boolean>
) {
    println(condition.name)
}

fun passedAsCondition(number: Int, multipleOf: Int): Boolean = number % multipleOf == 0

【讨论】:

  • 谢谢你,s1m0nw1。我在这里对 Kotlin 很陌生。是否可以从 lambda 中获取 passAsCondition 的函数名称?
  • FWIW,如果这个问题听起来不正统,您实际上可以在 C# 中执行此操作,过去在不使用硬编码字符串的情况下传递属性名称是半常见的。
  • @chris 所指的示例:this
  • @s1m0nw1:我明白了,但你不会失去将参数传递给passedAsCondition的能力吗?
  • 您仍然可以调用该函数,但参数需要作为额外参数传递,但它很快就会变得丑陋。无论如何,您的用例是什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多