2015-09-01 6 views
12

Scala hat eine generische identity Funktion im Predef:Hat Kotlin eine Identitätsfunktion?

def identity[A](x: A): A 

Does Kotlin eine ähnliche Anlage in der Standardbibliothek hat? Natürlich könnte ich einfach { it } stattdessen verwenden, aber ich finde identity einfacher zu lesen, und die Instantiierung all dieser Lambdas ist ein wenig verschwenderisch.

Ich muss diese identity Funktion an Orten verwenden können, wo eine Funktion (Foo) -> Foo erwartet wird, für jeden Typ Foo. Ist eine solche Funktion in Kotlins Typsystem überhaupt möglich? (Im Falle von Scala gibt es eine implizite Konvertierung, die das Verfahren in einem Funktionsobjekt oder etwas einwickelt.)

Antwort

10

Es gibt keine solche Funktion in dem Moment, aber man kann es leicht selbst definieren:

fun <T> identity(x: T): T = x 

Wenn Sie der Meinung sind, dass genügend Anwendungsfälle vorhanden sind, damit diese Funktion in der Kotlin-Standardbibliothek deklariert werden kann, reichen Sie bitte ein Problem unter youtrack.jetbrains.com ein. Vielen Dank!

+0

'val f: (String) -> String = identity' funktioniert nicht ... – fredoverflow

+1

Sie müssen ':: identity' schreiben, um ein Funktionsobjekt von einer Funktion zu instanziieren.Dies ähnelt den Methodenreferenzen von Java. –

+1

Hey! Ich habe einen Anwendungsfall für eine solche Funktion gefunden! Es ist die 'list.toMap (A, B)' Funktion wie hier: http://stackoverflow.com/questions/32935470/how-to-convert-list-to-map-in-kotlin/32938733#32938733 Berücksichtigen Sie, dass es 'fun it (x) = x ', als' list.toMap (:: it, {it.length}) 'gibt, konvertiert eine Liste in eine Map, in der die Elemente die Schlüssel sind. – voddan

6

Wenn Sie die Identity-Funktion als Parameter an eine andere Funktion übergeben müssen, können Sie einfach { it } verwenden. Zum Beispiel, es haben Sie eine Liste < Liste < String >> und wollen es auf eine Liste < String> abzuflachen, könnten Sie verwenden:

list.flatMap(identity) 

wo identity die Identitätsfunktion ist. Dies kann geschrieben werden als:

list.flatMap { it } 

Dies entspricht:

list.flatMap { x -> x } 

Die Alternative wäre die Identitätsfunktion irgendwo zu definieren, wie zum Beispiel:

val identity: (List<String>) -> List<String> = { it } 

Aber wir können‘ t Erstellen Sie ein generisches val, also müssten wir für jeden Typ eine Identitätsfunktion definieren. Die Lösung, (wie es in Java Function Schnittstelle erfolgt) es als eine konstante Funktion zu definieren ist:

fun <A> identity(): (A) -> A = { it } 

und verwenden Sie es als:

list.flatMap(identity) 

Natürlich ist es viel einfacher zu schreiben :

list.flatMap { it } 

für alle eine Identitätsfunktion einmal deklarieren (das für alle Arten funktionieren würde) ist nicht möglich, weil es parametriert werden müssen. Was möglich ist, ist eine Funktion zu verwenden, um diese Identitätsfunktion Rückkehr:

fun <T> identity(): (T) -> T = { it } 

Obwohl es die Aufgabe ist, ist es nicht sehr hilfreich, da man jetzt schreiben hat:

list.flatMap(identity()) 
+0

Einfacher zu schreiben, ja, aber es gibt Anwendungsfälle, wo eine definierte Identifizierungsfunktion unglaublich nützlich ist (wie eine allgemeine Sequenz von Stream-Operationen mit einer optionalen Filterstufe). –

+0

Was wäre der Typ dieser Funktion? Eine generische Wertfunktion wäre nicht möglich, da es keine Informationen zum Ableiten des Typs geben würde. Eine generische 'Spaß'-Funktion, die eine Wertfunktion zurückgibt, ist möglich, aber wahrscheinlich nicht wert. –

+0

Messepunkt. Der Use-Case, für den ich versuchte, es zu verwenden, lieferte eine Identity-Funktion für Collection.filter(), die zufällig Boolean zurückgegeben hat. In diesem Fall benutzte ich '{true}', aber das ist keine Identitätsfunktion. –