2015-09-01 27 views
12

Scala có identity hàm tổng quát trong Predef:Kotlin có chức năng nhận diện không?

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

Liệu Kotlin có một cơ sở tương tự trong thư viện chuẩn? Tất nhiên tôi chỉ đơn giản có thể sử dụng { it } thay vào đó, nhưng tôi thấy identity dễ đọc hơn, và instantiating tất cả những lambdas là một chút lãng phí.

Tôi phải có thể sử dụng chức năng identity này ở những nơi có chức năng (Foo) -> Foo, cho bất kỳ loại nào Foo. Có phải một chức năng như vậy có thể thực hiện được trong hệ thống kiểu của Kotlin không? (Trong trường hợp của Scala, có một chuyển đổi ngầm mà kết thúc tốt đẹp các phương pháp bên trong một đối tượng hàm hoặc một cái gì đó.)

Trả lời

10

Không có chức năng như vậy vào lúc này, nhưng bạn có thể dễ dàng xác định nó cho mình:

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

Nếu bạn nghĩ rằng có đủ trường hợp sử dụng cho hàm này được khai báo trong thư viện chuẩn Kotlin, vui lòng gửi một vấn đề tại youtrack.jetbrains.com. Cảm ơn!

+0

'val f: (String) -> String = identity' không hoạt động ... – fredoverflow

+1

Bạn cần viết ':: identity' để tạo một đối tượng hàm từ một hàm.Điều này tương tự như các tham chiếu phương thức của Java. –

+1

Hey! Tôi đã tìm thấy một trường hợp sử dụng cho một chức năng như vậy! Đó là hàm 'list.toMap (A, B)' như sau: http://stackoverflow.com/questions/32935470/how-to-convert-list-to-map-in-kotlin/32938733#32938733 Hãy xem xét rằng sẽ có 'vui nó (x) = x', hơn' list.toMap (:: it, {it.length}) 'chuyển đổi một danh sách thành một bản đồ trong đó các phần tử là các khóa. – voddan

6

Nếu bạn cần chuyển hàm nhận dạng làm tham số cho hàm khác, bạn có thể chỉ cần sử dụng { it }. Ví dụ, nó, bạn có một danh sách < Danh sách < Chuỗi >> và muốn san bằng nó vào một danh sách < String>, bạn có thể sử dụng:

list.flatMap(identity) 

nơi identity là chức năng nhận dạng. Điều này có thể được viết như sau:

list.flatMap { it } 

này tương đương với:

list.flatMap { x -> x } 

Việc thay thế sẽ được xác định chức năng nhận diện đâu đó, chẳng hạn như:

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

Nhưng chúng ta có thể' t tạo ra một chung val, vì vậy chúng tôi sẽ phải xác định một chức năng nhận dạng cho từng loại. Các giải pháp, (vì nó được thực hiện trong giao diện Java Function) là xác định nó như là một hàm liên tục:

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

và sử dụng nó như:

list.flatMap(identity) 

Tất nhiên, đó là dễ dàng hơn nhiều để viết :

list.flatMap { it } 

Tuyên bố chức năng nhận dạng một lần cho tất cả (có thể hoạt động cho tất cả các loại) là không thể vì nó sẽ phải được tham số hóa. Những gì có thể là sử dụng một hàm trả về chức năng danh tính này:

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

Mặc dù nó không công việc, nó không phải là rất hữu ích bởi vì người ta có hiện nay để viết:

list.flatMap(identity()) 
+0

Dễ viết hơn, có, nhưng có những trường hợp sử dụng có chức năng nhận dạng được xác định là vô cùng hữu ích (chẳng hạn như chuỗi hoạt động luồng có mục đích chung với một giai đoạn lọc tùy chọn). –

+0

Loại chức năng này là gì? Một hàm giá trị chung sẽ không thể thực hiện được vì sẽ không có thông tin nào để suy ra loại. Một hàm 'fun' chung trả về hàm giá trị là có thể, nhưng có lẽ không đáng giá. –

+0

Điểm công bằng. Trường hợp sử dụng tôi đã cố gắng sử dụng nó để cung cấp một nhận dạng func cho Collection.filter(), điều này sẽ xảy ra để trả về Boolean. Trong trường hợp đó, tôi đã kết thúc bằng cách sử dụng '{true}', nhưng đó không thực sự là một chức năng nhận dạng. –

Các vấn đề liên quan