2017-04-13 1 views
1

J'utilise un code de cette bibliothèque: https://github.com/Netflix-Skunkworks/rewriteComment appeler la méthode Kotlin avec plus d'une signature similaire avec lambda?

Quand j'appelle une de ses méthodes, je rencontre une erreur IDE:

None of the following functions can be called with the arguments supplied.

La méthode cible a deux signatures similaires:

data class CompilationUnit(...){ 

    fun refactor() = Refactor(this) 

    fun refactor(ops: Refactor.() -> Unit): Refactor { 
     val r = refactor() 
     ops(r) 
     return r 
    } 

    fun refactor(ops: Consumer<Refactor>): Refactor { 
     val r = refactor() 
     ops.accept(r) 
     return r 
    } 
} 

Le code d'appel dans Kotlin:

val unit: CompilationUnit =... 
unit.refactor{ tx -> 
    doSomeThing() 
} 

Et cet appel avec lambda est OK en Java:

CompilationUnit unit = .... 
unit.refactor(tx -> { 
    doSomeThing() 
}); 

Répondre

1

Vous pouvez fixer le code d'appel dans Kotlin: vous passez un lambda avec un argument { tx -> doSomething() }, mais un lambda avec récepteur et aucun argument est prévu là.

Comparer: (Refactor) -> Unit est le type for a function avec un argument, tandis que Refactor.() -> Unit désigne un function with receiver, qui ne prend aucun argument et est transmis au lieu d'un récepteur (this) de type Refactor. Ces types sont parfois interchangeables, mais les lambdas ne sont pas convertis entre eux implicitement.

Ainsi, vous pouvez appeler refactor comme suit:

val unit: CompilationUnit = ... 
unit.refactor { 
    doSomeThing() // this code can also work with `this` of type `Refactor` 
} 

Vous pouvez également appeler la surcharge avec Consumer<Refactor>, vous pouvez spécifier explicitement que:

unit.refactor(Consumer { tx -> doSomething() }) 

Implicite SAM conversion est, apparemment, pas disponible car il existe plusieurs surcharges avec des paramètres fonctionnels.