【问题标题】:From extension method to lambda with receiver, how?从扩展方法到带有接收器的 lambda,如何?
【发布时间】:2021-11-22 17:19:16
【问题描述】:
class SomeClass{
  val logger = ...
  fun (String).capitalizeLast():String {
    logger.info("capitalizeLast called")
    return this.substring(0,this.length-1) + this.substring(this.length-1,this.length).toUpperCase()
  }
  val asLambda: (String).()->String = <<dark magic using the previously defined extension method??
}


我的意思是,我总是可以写


val asLambda: (String).()->String = {
  this.capitalizeLast()
}

但是没有使用::的语法糖吗(和::println一样)

【问题讨论】:

  • 您希望将字符串的最后一个字母大写并保持其他字母不变。对吗?

标签: kotlin lambda extension-methods


【解决方案1】:

有一种更短的方法可以将最后一个字符大写。你可以这样做:

str.dropLast(1) + str.last().uppercase()

你可以用它做一个扩展功能:

fun String.capitalizeLast() = dropLast(1) + last().uppercase()

用法:

println("hello".capitalizeLast())

您可以使用String::capitalizeLast 引用此函数。示例:

val strings = listOf("hello", "world")
strings.map(String::capitalizeLast)

try it yourself

编辑:从您下面的评论中,在我看来,您想在变量中捕获一个函数,该函数具有参数和接收器。看看下面的例子:

fun Int.addLongGiveDouble(num: Long): Double {
    return (this + num).toDouble()
}

fun main() {
    val lambda: Int.(Long) -> Double = Int::addLongGiveDouble
    val result: Double = 5.lambda(10L) // result is 15.0
}

【讨论】:

  • 我想我毁了这个问题。我真正的问题,我发现我没有传达它,是关于使用该语法来处理带有接收器和参数的方法。 (SomeType).someMethod(someParam:SomeParam) ===&gt; (SomeType).(SomeParam)-&gt;Unit ...似乎语法在那里不起作用
  • 我已根据我从您的评论中理解的内容编辑了我的答案。这能回答你的问题吗?
  • 我收到错误消息“someMethod 同时是成员和扩展。不允许引用此类元素”。我认为问题在于我的扩展方法是在一个类中定义的,这不起作用
  • 你能分享你正在尝试的确切代码吗?您可以将其添加到问题本身。
  • 完成@Arpit Shukla
【解决方案2】:

Lambda 在这里是错误的术语。 Lambda 只是功能对象的一种语法替代方案。函数对象不是 lambda。您正在尝试从扩展函数中获取函数对象。

扩展函数和成员函数是一样的:

val asFunctionObject: String.()->String = String::capitalizeLast

请注意,String.() -&gt; String(String) -&gt; String 实际上是同一类型。区别仅在它用作函数参数的类型时才重要,并且当 lambda 语法与高阶函数一起使用时会影响 lambda 的解析方式。

【讨论】:

    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多