fold và getOrElse với Option trong scala
Scala
50
White

LinhPT viết ngày 23/05/2015

alt text

Giá trị null trong scala được giải quyết bằng sự tồn tại của Option
Thường khi sử dụng một giá trị Option chúng ta hay sử dụng hàm getOrElse

Cơ bản về Option và getOrElse

Trường hợp Option hay được sử dụng là khi mà chúng ta cần lấy một giá trị ra khỏi

val x = Map(1 -> 2)
val y = x.get(1)

Hàm get của Map trong scala được implement trong trait MapLike và có định nghĩa như sau:

def get(key : A) : scala.Option[B]

Hàm đó có ý nghĩa là giá trị mà lấy ra khi get 1 key trong map có thể tồn tại hoặc không tồn tại

scala> val b = a.get(2)
b: Option[Int] = None

scala> val b = a.get(1)
b: Option[Int] = Some(2)

Do đó khi muốn sử dụng giá trị lấy ra từ map dưới dạng nguyên thuỷ (ở đây là Int) thì chúng ta cần sử dụng hàm getOrElse

scala> val b = a.get(2).getOrElse(3)
b: Int = 3

Cách sử dụng rất dễ hiểu như chính cái tên của nó, lấy ra giá trị đã có, hoặc là nếu không có thì sẽ là [].

Sử dụng fold thay thế cho getOrElse

Từ scala 2.10 thì hàm #fold được cho vào trong Option với cách dùng tương tự, nhưng interface ngược với getOrElse

fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B

Nhìn interface này chúng ta sẽ thấy fold nhận vào 2 function, function đầu tiên sẽ được evaluate khi Option là None, còn ngược lại sẽ evaluate function thứ 2.

Vậy logic về getOrElse sẽ được viết lại như sau:

val b = a.get(1).fold[Int](3)(x => x)

Nên dùng fold hay getOrElse

Các bạn tinh ý một chút có thể nhận ra việc sử dụng hàm fold "khuyến khích" người ta nghĩ theo chiều hướng functional hơn, tức là kết quả trả về sẽ là 1 hàm (A) => B, tức là trong trường hợp bạn muốn có kết quả giống như getOrElse, tức là có gì nhận nấy, thì bạn phải truyền vào một hàm có dạng (x => x).

Diễn đạt bằng lời nói, chúng ta có thể hiểu là

fold: Lấy kết quả từ một cấu trúc X, khi không tồn tại thì thực hiện thao tác Y
getOrElse: Lấy kết quả từ cấu trúc X, khi không tồn tại thì trả về giá trị Z

Chúng ta có thể làm điều tương tự fold với getOrElse bằng cách sử dụng map

val b = a.get(1).map(x=>x).getOrElse(2)

Nên sử dụng fold hay getOrElse là tuỳ "taste" của bạn, tuy nhiên tôi thích sử dụng fold hơn :).

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

LinhPT

20 bài viết.
62 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
39 3
Mình thi thoảng phải quản lý linux server, mà trong đó có một số thao tác quản lý quan trong như quản lý đĩa cứng, quản lý mạng, quản lý đường truy...
LinhPT viết 3 năm trước
39 3
White
27 2
(Ảnh) Tiêu đề chỉ là câu khách :v, thực ra là có một vài điểm về mysql explain mà chắc chưa nhiều bạn biết, tớ cũng hay quên nên note lại cho nhớ ...
LinhPT viết 3 năm trước
27 2
White
18 0
Bài viết được dịch từ http://qiita.com/sion_cojp/items/04a2aa76a1021fe77079 Điều cần nhớ trước khi đánh bất kì câu lệnh nào ①Để tránh làm nặng...
LinhPT viết hơn 1 năm trước
18 0
Bài viết liên quan
White
10 0
Kí tự Regex cơ bản Về cơ bản thì các sử lý matching của scala.util.matching.Regex sẽ được "phó thác" (delegate) cho java Regex. Bạn có thể tạo một ...
huydx viết hơn 3 năm trước
10 0
White
7 1
Trong scala kí tự _ được dùng với khá nhiều mục đích .. không liên quan đến nhau. Tạm note lại cái đã khi nào có time sẽ quay lại viết cẩn thận sa...
huydx viết hơn 3 năm trước
7 1
White
1 0
(Bài viết hơi khó hiểu, dành cho bạn nào có hứng thú với type programming trong scala với các thư viện như shapeless chẳng hạn) Thông thường với m...
huydx viết hơn 2 năm trước
1 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
20 bài viết.
62 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!