【问题标题】:How to set default lambda function for named lambda argument with generics in Kotlin?如何在 Kotlin 中使用泛型为命名 lambda 参数设置默认 lambda 函数?
【发布时间】:2018-08-29 16:18:27
【问题描述】:

此代码打印“Hello 1”。 parseInput 有两个泛型类型,第一个 arg 是第一个泛型类型 A 的简单对象,第二个 arg 是假设将泛型类型 A 更改为泛型 B 的函数。如您所见,它在以下工作正常.

fun toGreeting(input : Int) : String {
    return "hello " + input
}

fun <A, B> parseInput(raw : A, toB : (raw : A) -> B) : B {
    return toB(raw)
}

fun main(args: Array<String>) {
    val greeting = parseInput(1, ::toGreeting)
    println(greeting)
}

问题是如何为parseInput 中的第二个命名参数提供默认的 lambda 值。所以我可以通过提供第一个参数来调用这个函数,并让它使用默认的 lambda 函数。

val greeting = parseInput(1)
println(greeting)

【问题讨论】:

  • 您想指定什么作为默认值?默认值只能是从Any到Any的函数,适合这个签名的有用函数并不多。
  • 这里似乎连(Any) -&gt; Any 函数都不能作为默认值。由于涉及泛型,因此需要一个泛型(A) -&gt; B 函数,然后强制调用者指定泛型类型,因为无法推断B。至于这个默认函数的实现,你可以在其中将一些东西强制转换为B(这可能不会成功),或者让它返回Nothing(这不是你想要的在这里)。
  • @yole,一个空的,Unit 可以作为默认值。
  • 所以您希望第二个示例中的greeting 等于Unit?这有什么用?
  • @yole,是的,它没用,但我希望它在调用函数时没有提供它是没用的。我的目标是使第二个函数可选,这就是为什么我想要一个默认的 lambda 函数返回 Unit

标签: generics lambda kotlin anonymous-function named-parameters


【解决方案1】:

您的要求是矛盾的。您希望能够为任何 B 指定一个返回 B 类型值的函数(这本身实际上是不可能的;唯一可能的此类函数是始终抛出异常的函数),并且您还希望编译器是当您没有向编译器提供任何可以确定它的信息时,能够推断出 B 是什么。在您的示例中:

 val greeting = parseInput(1)  
 println(greeting)

...编译器可以从中确定greeting 变量需要具有什么类型的信息为零。在这种情况下,没有任何逻辑可以替代 Unit 或任何其他特定类型;相反,正如您在评论中正确指出的那样,此代码无法编译。

如果你想让greeting在这种情况下成为Unit,你可以通过简单地重载函数来实现:

fun <A> parseInput(raw: A) {
}

此函数将返回 Unit,为您提供您正在寻找的确切行为。

【讨论】:

  • 重载会起作用,但这不是我想要的。如果我还有一些其他的逻辑需要在这个parseInput中处理?我将不得不在重载函数中复制它们。我可以将通用逻辑移到另一个可以在重载函数parseInput 中调用的函数中,但这也不是我想做的。
  • parseInput(1, ::toGreeting) 有效,因为 toGreeting 提供了要返回的类型。 parseInput(1) 失败是对的,因为没有提供给编译器的类型来推断 B 是什么。所以这又回到了这个问题,有没有办法在函数签名中提供像 toGreeting 这样的默认函数?
  • 没有办法以编译器从该默认函数中获取类型参数的方式指定默认函数。
  • 如果有办法这样做就好了!
  • 只是在这里插话说能够做到fun &lt;A, B&gt; parseInput(raw : A, toB : (raw : A) -&gt; B = { it }) : B {} 会很棒,在这种情况下,很明显 B 与 A 是同一类型。
猜你喜欢
  • 1970-01-01
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
相关资源
最近更新 更多