- vừa được xem lúc

Higher-order Function & Lambda

0 0 35

Người đăng: Hoàng Việt Ngô

Theo Viblo Asia

1. Higher-order function là gì ?

  • Thuật ngữ "Functional programming" là một dạng lập trình mà ta có thể truyền các hàm như 1 tham số hay return 1 hàm , Higher-order function là một dạng như vậy

Dưới đây là hai kiểu thể hiện cơ bản của Higher-order function :

1. Higher-order function được truyền như tham số

Ta có ví dụ một Higher-order function như sau :

fun printPerson(name: String , printName: (Int?) -> String) { printName(name) }
  • Function reference :
fun printName(name: String) { println(name)
}
fun printPerson("VietKFC" , ::printName)

Ta thấy function printName được gọi tham chiếu trong function printPerson()

  • Anonymous function :

Ta sẽ truyền như những function bình thường và định nghĩa luôn ở đây , khác chỗ đây sẽ là 1 function không có tên :

fun printPerson("Viet" , fun(name: String?) : Unit { // Do something with name...
})

2. Trả về một function

fun printPerson() : ((Int) -> Unit) { return ::getAge
}
fun getAge(age: Int) { println(age)
}
printPerson()(22)
  • Hạn chế khi sử dụng higher-order function :

Các param có dạng function type được truyền vào sẽ tự động tạo ra một Function Object trong memory để lưu các function này , làm tăng số lượng function trong app ở run-time.

 private fun makeHighOrder(action: () -> Int) { action() }
 private final void makeHighOrder(Function0 action) { action.invoke(); }

Ta thấy sau khi decomplie sang java code thì Object Function0 được sinh ra trong memory.

2. Lambdas

Lambda expression là một hàm ẩn danh được định nghĩa trong {} và có thể coi như một giá trị . Chúng có thể được truyền như một tham số hoặc làm bất cứ điều gì như đối với 1 Object.

val lambda : (Int , Int) -> Int = {a,b -> a+b}
println(lambda(2,3))

Ta cũng có thể truyền Lambda vào Higher-order function :

private fun sumNumber(a: Int , b: Int , plus: (Int,Int) -> Int) { println(plus(a,b))
}
val plus : (Int,Int) -> Int = {a,b -> a+b}
sumNumber(2,3,plus)
  • Function literal , cũng là một cách gọi khác của Lambda Function có 1 tham số
val nameList = arrayOf("Viet" , "Hong" , "Huyen" , "Long" , "Quang")
val newName = nameList.filter{ name -> name.contains("n" , ignoreCase = true) } .sortBy{name -> name.length}
  • Sự khác nhau giữa Lambda và Anonymous Function :

Anonymous function có thể xử lý và trả về như 1 hàm bình thường , còn Lambda chỉ trả về giá trị cuối cùng , nếu muốn xử lý rẽ nhánh ta cần thêm label để định nghĩa, ví dụ :

val anonymousFunc = fun(s: String) : Boolean {
if(s.contains("v")) return true
return false
}
val lambdaFunction: (String) -> Boolean = _@.com{s ->
if(s.contains("v")) return@lambda true
// nếu ko có label @lambda , câu lệnh if sẽ bị bỏ qua
false
}

3. Closure

  • Closure là những hàm có thể truy cập và sửa đổi những biến được đăng kí bên ngoài phạm vi

  • Lambda expression và Anonymous function cho phép truy cập vào closure và sửa đổi những biến này

Từ Java 8 hoặc Kotlin có sử dụng lambda , ta có ví dụ so sánh như sau :

int sum = 0;
List<Integer> list = Arrays.asList(1,2,3,4,5);
Thread thread = new Thread(() -> { for(int i = 0 ; i< list.size() ; i++) { sum += i; // Báo lỗi khi modify biến sum... }
});
thread.start();

Với Lambda expression :

var sum = 0
val list = listOf(1,2,3,4,5)
val thread = Thread{ list.forEach {sum += i} }
thread.start()

4. Inline function

Quay trở lại vấn đề về việc 1 Function Object sẽ được sinh ra khi sử dụng function như một tham số , Inline Function sinh ra để khắc phục điều này.

Ta thêm "inline" vào trước mỗi Higher-order function

fun showPerson(name: String , getAge: (Int?) -> Int { println(name) println(getAge(22))
}
showPerson("viet" , fun(age: Int?): Int { return 22
})

Thông thường sau khi decomplie , ta có 1 Object tên là Function1 được sinh ra

public final showPerson(Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
INVOKEVIRTUAL com/example/kotlindemo/MainActivity.showPerson(Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V

Sau khi sử dụng inline function và decomplie lại ta thấy Object Function1 đã biến mất

LOCALVARIABLE this_$iv Lcom/example/kotlindemo/MainActivity; L1 L15 2
LOCALVARIABLE name$iv Ljava/lang/String; L1 L15 3
LOCALVARIABLE $i$f$showPerson I L2 L15 4
  • Tuy nhiên , Inline Function cũng đi kèm một số nhược điểm sau :
  1. Inline function không thể gọi gián tiếp từ inline function khác hay gọi chính nó
  2. 1 public inline function chỉ có thể truy cập vào public class và public field của class đó
  3. Nó có thể sinh ra thêm nhiều code vì implement của nó được gọi ở nhiều nơi
  4. Nếu dùng nhiều sẽ làm giảm tốc độ truy cập của bộ nhớ đệm

---> Ta nên sử dụng Inline Function cho những khối code ngắn gọn và hạn chế sử dụng chúng bừa bãi

Bình luận

Bài viết tương tự

- vừa được xem lúc

Kotlin dễ ẹc - Lớp vs đối tượng: Object expression và Object declaration

Khi nào dùng. . Khi muốn tạo một đối tượng với những sự thay đổi nhỏ của lớp mà không phải khai báo tường minh lớp con của lớp đó. .

0 0 37

- vừa được xem lúc

Làm đoạn code Kotlin của bạn dễ đọc hơn với 5 Extensions này.

Bạn có thể đã xem qua nhiều bài viết về Kotlin Extension, nhưng bài viết này không phải là tất cả về Extension. Đó là về việc làm cho code của bạn trở nên dễ đọc hơn, vì vậy tôi đã tập trung vào việc giải thích và đưa ra các tiện ích mở rộng hàng đầu của tôi để làm code bạn tự nhiên nhất có thể.

0 0 46

- vừa được xem lúc

Phòng tránh NullPointerException trong Android Kotlin

I. Dẫn nhập. . Như chúng ta đã biết một trong những điểm nổi trội của Kotlin so với Java đó là khả năng xử lý null vô cùng hiệu quả.

0 0 50

- vừa được xem lúc

KOTLIN - 10 MẸO VÀ THỦ THUẬT LÀM VIỆC VỚI LIST

Giới thiệu. List (danh sách) là một Collection trong Kotlin.

0 0 52

- vừa được xem lúc

Navigation Component

Introduction. Navigation Component are in simple terms, components required to perform navigations and Navigation refers to the interactions that allow users to navigate across various areas within th

0 0 34

- vừa được xem lúc

Flutter Vs Kotlin Multiplatform Mobile (KMM) Vs React Native

Trong phát triển đa nền tảng hiện nay chúng ta đang có nhiều tùy chọn như Flutter, React Native và bây giờ là Kotlin Multiplatform Mobile. Bây giờ mối quan tâm là chúng ta phải chọn công nghệ nào tron

0 0 107