2015-09-01 4 views
12

Scala имеет общую identity функцию в Predef:Имеет ли Kotlin функцию идентификации?

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

ли Котлин иметь аналогичный объект в стандартной библиотеке? Конечно, я мог бы просто использовать { it } вместо этого, но найти identity проще для чтения, а создание экземпляров всех этих лямбдов немного расточительно.

Я должен быть в состоянии использовать эту функцию identity в тех местах, где ожидается функция (Foo) -> Foo, для любого типа Foo. Возможна ли такая функция в системе типов Котлина? (В случае Scala, есть неявное преобразование, который оборачивает метод внутри объекта функции или что-то.)

ответ

10

Там нет такой функции в данный момент, но вы можете легко определить его самостоятельно:

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

Если вы считаете, что достаточно использовать эту функцию в стандартной библиотеке Kotlin, отправьте ее по адресу youtrack.jetbrains.com. Благодаря!

+0

'VAL F: (String) -> String = identity' не работает ... – fredoverflow

+1

Вам нужно написать ':: identity', чтобы создать экземпляр объекта функции из функции.Это похоже на ссылки на методы Java. –

+1

Эй! Я нашел прецедент для такой функции! Это функция 'list.toMap (A, B)', как здесь: http://stackoverflow.com/questions/32935470/how-to-convert-list-to-map-in-kotlin/32938733#32938733 Подумайте, что будет 'fun it (x) = x', чем' list.toMap (:: it, {it.length}) 'преобразует список в карту, где элементы являются ключами. – voddan

6

Если вам нужно передать функцию идентификации как параметр в другую функцию, вы можете просто использовать { it }. Например, у вас есть список < < Список строк >> и хотите, чтобы сгладить его в списке < String>, вы можете использовать:

list.flatMap(identity) 

где identity является тождественной функции. Это можно записать в виде:

list.flatMap { it } 

Это эквивалентно:

list.flatMap { x -> x } 

Альтернативой было бы определить функцию тождества где-то, например:

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

Но мы можем» t создать общий val, поэтому нам нужно будет определить функцию идентификации для каждого типа. Решение, (как это делается в интерфейсе Java Function) является определение его как постоянную функцию:

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

и использовать его как:

list.flatMap(identity) 

Конечно, гораздо проще написать :

list.flatMap { it } 

Объявив функцию идентичности один раз для всех (которые будут работать для всех типов) не представляется возможным, поскольку она должна была бы быть параметризованы. Что такое возможно, чтобы использовать функцию возвращать тождественную функцию:

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

Хотя это работа, это не очень полезно, так как один теперь должен написать:

list.flatMap(identity()) 
+0

Легче писать, да, но есть варианты использования, когда определенная функция идентификации невероятно полезна (например, универсальная последовательность операций потока с необязательной стадией фильтра). –

+0

Каким будет тип этой функции? Общая функция значения не была бы возможна, потому что не было никакой информации о выводе типа. Возможна общая функция 'fun', возвращающая функцию значения, но, вероятно, ее не стоит. –

+0

Справедливая точка. Случай использования, к которому я пытался использовать его, - это предоставление функции identity в Collection.filter(), которая возвращает Boolean. В этом случае я закончил использование '{true}', но это не действительно функция идентификации. –

Смежные вопросы