2

因此,虽然这对于 gradle 特定问题来说是一个相当大的 kotlin-dsl,但我认为它总体上适用于 kotlin 语言本身,所以我不打算使用该标签。

在 gradle API 中,类Action<T>定义为:

@HasImplicitReceiver
public interface Action<T> {
    /**
     * Performs this action against the given object.
     *
     * @param t The object to perform the action on.
     */
    void execute(T t);
 }

所以理想情况下,这应该在 kotlin 中工作(因为它是一个带有 SAM 的类):

val x : Action<String> = {
    println(">> ${it.trim(0)}")
    Unit
}

但我收到以下两个错误:

Unresolved reference it
Expected Action<String> but found () -> Unit

Fwiw,甚至Action<String> = { input: String -> ... }不起作用。

现在这是真正有趣的部分。如果我在 IntelliJ 中执行以下操作(顺便说一句,有效):

object : Action<String> {
    override fun execute(t: String?) {
        ...
    }
}

IntelliJ 弹出建议Convert to lambda,当我这样做时,我得到:

val x = Action<String> {
}

哪个更好,但it仍未解决。现在指定它:

val x = Action<String> { input -> ... }

给出以下错误Could not infer type for inputExpected no parameters. 有人可以帮我解决发生了什么吗?

4

2 回答 2

3

这是因为Actiongradle 中的类是用HasImplicitReceiver. 从文档中:

将 SAM 接口标记为 lambda 表达式/闭包的目标,其中单个参数作为调用的隐式接收器(this在 Kotlin中,delegate在 Groovy 中)传递,就好像 lambda 表达式是参数类型的扩展方法一样。

(强调我的)

所以,下面的编译就好了:

val x = Action<String> {
    println(">> ${this.trim()}")
}

你甚至可以只写${trim()}并省略this它前面的。

于 2017-12-24T07:07:05.630 回答
0

您需要使用类名引用该函数,例如:

val x: Action<String> = Action { println(it) }
于 2017-12-20T14:40:46.117 回答