2017-12-20 22 views
2

これはgradle特有の問題のためのかなりのkotlin-dslですが、全体的にはkotlin言語そのものに当てはまると思いますので、私はそのタグを使用しません。 GradleのAPIでKotlinはgradleのActionクラスをlambdaに変換できません

は、クラス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); 
} 

(それはSAMとクラスであるため)、これはkotlinで動作するはずです:

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

しかし、

Fwiw、さらにAction<String> = { input: String -> ... }が表示されます。動作しません。

ここでは本当に興味深い部分があります。私は(ところで、働く)のIntelliJで次の手順を実行している場合:

val x = Action<String> { 
} 

良いですが、itはまだです:

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

IntelliJのは私が行うとき、私が得る提案Convert to lambdaを、ポップ未解決。今、それを指定:

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

は、次のエラーを与えCould not infer type for inputExpected no parameters。誰かが何が起こっていると私を助けることができますか?

+0

すべてがうまく動作します。たぶん古いKotlinプラグインのバージョンですか? – FWeigl

答えて

2

。ドキュメントから:

単一のパラメータがあたかも呼び出し(Kotlin、グルービーでdelegatethis)の暗黙的な受信機として渡されるラムダ式/クロージャのための標的としてのSAMインタフェースをマークラムダ式は、拡張メソッドのパラメータタイプでした。

(強調鉱山)

ので、以下はうまくコンパイル:

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

あなたもちょうど${trim()}を書き、その前にthisを省略することができます。

0

あなたは次のように、クラス名と関数を参照する必要がありますのGradleでActionクラスはHasImplicitReceiverと注釈されているので、これがある

val x: Action<String> = Action { println(it) } 
+0

これは本当に変ですが、どういうわけか 'Action {println(this)}'はうまくいくようです。私はラムダがなぜ単一のパラメータよりもレシーバで扱われているのか分かりませんが、それは少なくともグラデルビルドの文脈では答えのようです。しかし、私は、コンパイラがグラデーションスクリプトに対して異なった振る舞いをするとは思わないでしょうか? –

関連する問題