2016-12-20 2 views
2

ich mit diesem Stück Code den folgenden Fehler habe, die mir keinen Sinn macht:Können Sie nicht in einem Runnable SAM in Kotlin zurückkehren?

fun spawnWorker(): Runnable { 
    return Runnable { 
     LOG.info("I am a potato!") 
     return 
    } 
} 

mir meine IDE sagt dies:

enter image description here

Aber die Schnittstelle Runnable sagt etwas anderes :

@FunctionalInterface 
public interface Runnable { 
    public abstract void run(); 
} 

Was ist der Grund, warum ich keine Rückkehr gibt, aber ohne Rückkehr haben es kompiliert fein:

fun spawnWorker(): Runnable { 
    return Runnable { 
     LOG.info("I am a potato!") 
    } 
} 

Antwort

7

Eine einfache return gibt von der nächsten umschließenden Funktion oder anonymen Funktion zurück. In Ihrem Beispiel ist die Rückgabe nicht lokal und kommt von spawnWorker und nicht vom SAM-Adapter Runnable zurück. Für einen lokalen Gegenzug verwendet die Bezeichnung Version:

fun spawnWorker(): Runnable { 
    return Runnable { 
     LOG.info("I am a potato!") 
     [email protected] 
    } 
} 
+0

Dank! Ich war mir nicht bewusst, dass der Kotlin-Compiler nicht den Umfang überprüfen konnte, in dem ich diese Rückkehr verwende, es ist das erste Mal, dass ich dieses Verhalten in einer funktionalen Sprache sehe. – PedroD

+2

Es ist nicht so, dass der Compiler den Gültigkeitsbereich nicht überprüfen konnte, sondern tatsächlich den Gültigkeitsbereich überprüft und die nicht lokale Rückkehr aus diesem Gültigkeitsbereich verbietet. Die return-Anweisung wurde absichtlich so entworfen, dass sie von der nächsten Nicht-Lambda-Funktion zurückkehrte, um Inline-Funktionen mit lambdas zu aktivieren, wie 'forEach',' synchronized' usw., die wie Sprachkonstrukte aussehen. Weitere Details zu Rücksendeanweisungen finden Sie hier: https://kotlinlang.org/docs/reference/returns.html#return-at-labels – Ilya

2

Sie eine Lambda-to-SAM Umwandlung verwendet wird, so versucht, von einer Lambda-Anweisung zurück, was nicht erlaubt ist eine Rückkehr auf seinem eigenen haben.

Ihr Code

fun spawnWorker(): Runnable { 
    return Runnable { LOG.info("I am a potato!") } 
} 

die gleiche Bedeutung wie

fun spawnWorker(): Runnable { 
    return { LOG.info("I am a potato!") } 
} 

es vergleichen, ein Objekt zurückkehrt, die die direkte Übersetzung von Java ist:

fun spawnWorker(): Runnable { 
    return object : Runnable { 
     override fun run() { 
      LOG.info("I am a potato!") 
      return // don't really need that one 
     } 
    } 
} 
Verwandte Themen