Home » Scala » [scala] Phân biệt : function literal – function value – closure

[scala] Phân biệt : function literal – function value – closure

I – function literal

1 – Khái niệm

Function literal là 1 funtion ẩn danh (mặc định không có tên) và bạn có thể gán cho nó 1 cái tên bằng cách binding nó với 1 variable
ví dụ :
Khai báo 1 vài Function literal

scala> (a:Int, b:Int) => a + b
res0: (Int, Int) => Int = <function1>
scala> (i: Int) => { i * 2 }
res1: Int => Int =<function2>

Function literal xuất hiện thường xuyên trong scala, giả sử ta có 1 list từ 1->9 và muốn lấy ra những số chia hết cho 2 :

scala> val x = List.range(1, 10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> val evens = x.filter((i: Int) => i % 2 == 0)
evens: List[Int] = List(2, 4, 6, 8)

bạn sẽ thấy : (i: Int) => i % 2 == 0 – là 1 Function literal
Và bạn có thể gán nó cho 1 variable:

scala> val double = (i: Int) => { i * 2 }
double: Int => Int =<function3>

scala> val dv = (i: Int) => i % 2 == 0
dv: Int => Boolean =<function4>

*một số khái niệm về Function literal :

safaribooksonline.com – scala
function literal is an anonymous function—also known as a function literal

wikibooks.org
It often occurs that a function is defined only to be used once.
Since it is only defined once, it is somewhat superfluous to give it a name.
To avoid repeatedly naming and using functions once, there exists a facility to just avoid naming them at all.
These are called anonymous functions or function literals.

2 – Ứng dụng của Function literal

Như ví dụ trên nó rất hữu dụng khi chúng ta muốn pass 1 function như 1 argument vào method mà không muốn viết thành 1 function mới riêng rẽ
Ví dụ :

scala> val x = List.range(1, 10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> val evens = x.filter((i: Int) => i % 2 == 0)
evens: List[Int] = List(2, 4, 6, 8)

II – function value

Sử dụng luôn ví dụ trước

scala> val double = (i: Int) => { i * 2 }
double: Int => Int =<function5>

Variable double là 1 instance, cũng như các instance khác như String, Int,vv , trong trường hợp này nó là instance của 1 function, nó được coi là 1 function value và được sử dụng như 1 funtion :

scala> double(4)
res0: Int = 8

làm lại ví dụ trên bằng cách khởi tạo 1 function value :

scala> val x = List.range(1, 10)
x: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

khởi tạo function value tên ft

scala> val ft = (i: Int) => i % 2 == 0
ft: Int => Boolean =<function6>

truyền ft như 1 argument vào filter và sử dụng placeholder( “_” )

scala> val evens = x.filter(ft(_))
evens: List[Int] = List(2, 4, 6, 8)

III – closure

Closure là 1 funtion mà giá trị trả về của nó thay đổi bởi 1 hoặc nhiều variables được định nghĩa ở bên ngoài function
ví dụ :
đây đơn thuần là 1 function literal

val multiplier = (i:Int) => i * 10

ta thay 10 bằng 1 biến được khai báo trước đó,bên ngoài function :

val multiplier = (i:Int) => i * factor

giá trị trả về bây giờ phụ thuộc vào giá trị của factor nên nó là 1 closure
theo định nghĩa của Programming in Scala trang 197 :
closure : A function object that captures free variables, and is said to be “closed” over the variables visible at the time it is created