[Scala] - day 2 : Expressions và Conditionals trong Scala

I - Expressions

Expressions được hiểu như là 1 đơn vị code (single unit of code) mà trả về 1 giá trị nào đó.
Ví dụ : 
scala> "đây là 1 expression"
res0: String = đây là 1 expression
Chúng ta đơn giản vừa tạo ra 1  expression bằng 1 String literal ,hãy thử làm nó phức tạp hơn chút :
scala> "đây là " + 1 + " expression"
res1: String = đây là 1 expression
Như bạn thấy ta có cùng 1 kết quả  , cũng như mục đích của 1  expression là trả về  1 giá trị nào đó và sử dụng được.

Expression Blocks

Bạn có thể nhóm nhiều expression bằng {} ,mỗi cụm {} được gọi là 1 expression block.
Ví dụ :
scala> val tenToi : String = "HoaiPT" ; "toi ten la " + tenToi
tenToi: String = HoaiPT
res2: String = toi ten la HoaiPT

scala> val tuGioiThieu = {val tenToi : String = "HoaiPT" ; "toi ten la " + tenToi}
tuGioiThieu: String = toi ten la HoaiPT
Bạn có thể dùng Expression Block để nhóm nhiều dòng code :
scala> val tuGioiThieu = {
           |  val tenToi : String = "HoaiPT"
           |  "toi ten la " + tenToi
           | }
tuGioiThieu: String = toi ten la HoaiPT
 Mỗi Expression Block có biến riêng chỉ tồn tại trong block và trả về 1 value,và block child có thể gọi biến của block parent.
scala> val tinhTong = {val parent = 1;{val child = parent + 1;child}}
tinhTong: Int = 2
Với những ví dụ trên bạn có thể chưa thây được lý do phải dùng expression block nhưng trước mắt hãy nắm được để có thể hiểu được về cấu trúc và code syntax.

Statement

Đến đây 1 số bạn sẽ tự hỏi vậy những expression không trả về value thì sao?Chúng ta gọi chúng là Statement - những expression không trả về giá trị nào hay có thể nói chúng trả về 1 Unit.
scala> println("tôi tên là Hoài")
tôi tên là Hoài
scala> val luckyNumber = 49
luckyNumber: Int = 49
Như các bạn đã biết println() trả về 1 Unit ,ở ví dụ thứ 2 nó không trả về 1 giá trị nào,ở đây đơn giản là 1 biến được khởi tạo và bạn có thể dùng lại biến đó ở nơi khác.

II - Conditionals

If..Else Expression Blocks 

Syntax:
if (<Boolean expression>) <expression>
else <expression>
Boolean expression là 1 expression trả về 1 giá trị Boolean : True or False.
If..Else là 1 expression nghĩa là nó có thể trả về cho bạn 1 value nào đó hay Unit.
Ví dụ : 
scala> val so1 = 1so1: Int = 1
scala> val so2 = 2so2: Int = 2
scala> val soSanh2So = if(so1 > so2) so1 else so2 soSanh2So: Int = 2
scala> val soSanh2So = if(so1 > so2) println("vo ly") else so2 soSanh2So: AnyVal = 2
Ở ví dụ cuối If và Else trả về 2 kiểu giá trị khác nhau nên biến soSanh2So mang kiểu AnyVal.

Match Expressions

Giống như switch ở nhiều ngôn ngữ khác ,match trong scala cho phép bạn duyệt 1 input item bằng các pattern và chỉ pattern đầu tiên thoả mãn được thực thi.Cũng như các ngôn ngữ khác match hỗ trợ default hay wildcard.
Syntax:
<expression> match {
 case <pattern match> => <expression>
 [case...]
}
 Ví dụ :
Ta viết lại ví dụ If..Else bằng Match
scala> val soSanh2So = so1 > so2 match {
        | case true => println("vo ly")
        | case false => so2
        | }
soSanh2So: AnyVal = 2
Nếu bạn đưa cho match 1 input mà không map với bất kì 1 pattern nào trong match đó sẽ trả về lỗi:
scala> 3 match {
       | case 1 => "đây là số 1"
       | case 2 => "đây là số 2"
       | }
scala.MatchError: 3 (of class java.lang.Integer)
... 39 elided 
Ví dụ khác với default value :
scala> val ten = "Hoai"
ten: String = Hoai
scala> ten match {
       | case "Hoai" => "chào Hoài"
       | case _ => "chào đằng ấy"
       | }
res4: String = chào Hoài
Match hỗ trợ bạn duyệt 1 input item với nhiều pattern 1 lúc :
scala> val ngayTrongTuan = "thu 2"
ngayTrongTuan: String = thu 2
scala> ngayTrongTuan match {
        | case "thu 2" | "thu 3" | "thu 4" | "thu 5" | "thu 6" => "ngay de lam viec"
        | case _ => "ngay de choi"
        | }
res5: String = ngay de lam viec
Match với Pattern Guards : hiểu đơn giản là bạn sẽ kiểm tra thêm 1 lần nữa trước khi thực thi
expression  
scala> soBatKy match {
       | case soNhoHon5 if soNhoHon5 < 5 => "đúng là nhỏ hơn 5 rồi"
       | case soBang5 if soBang5 == 5 => "đúng là bằng 5"
       | case _ => "lớn hơn 5 hoặc kiểu dữ liệu k đúng"
       | }
res8: String = đúng là bằng 5
 Match hỗ trợ bạn check kiểu của input item
scala> val caiGiDo: Any = 5
caiGiDo: Any = 5
scala> caiGiDo match {
       | case kieuSoInt : Int => "đây là kiểu số"
       | case kieuString : String => "đây là kiểu string"
       | case _ => "mệt rồi nên kiểu gì cũng được"
       | }
res10: String = đây là kiểu số

Loops 

Loops trong Scala tương tự như ngôn ngữ khác nhưng nó được gọi là 1 expression nghĩa là nó sẽ trả về 1 giá trị này đó hoặc Unit sau khi thực thi.Có 2 cách để define loop trong Scala :
Syntax
for (<starting integer> [to|until] <ending integer> [by increment])[<expression>]
for (<identifier> <- <iterator>) [yield] [<expression>]
Với cách đầu tiên bạn sẽ cần 1 Numeric Range , ở đây tôi ví dụ chạy từ 1 đến 10 :
scala> for (i <- 1 to 10) println("đây là số "+ i)
đây là số 1
đây là số 2
đây là số 3
đây là số 4
đây là số 5
đây là số 6
đây là số 7
đây là số 8
đây là số 9
đây là số 10
Với cách thứ 2 bạn thường dùng khi không rõ cần loop bao nhiêu lần :
scala> val daySo: List[Int] = List(1,2,3,4,5)
daySo: List[Int] = List(1, 2, 3, 4, 5)
scala> for (so <- daySo) println("đây là số "+ so)
đây là số 1
đây là số 2
đây là số 3
đây là số 4
đây là số 5
Ở đây bạn sẽ tự hỏi làm sao để có thể trả về value sau khi kết thúc loop , bạn fai dùng yield ,ta viết lại 2 ví dụ trên có sử dụng yield :
scala> for (i <- 1 to 10) yield i
res14: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> for (so <- daySo) yield so
res15: List[Int] = List(1, 2, 3, 4, 5)
Bạn có thể hiểu đơn giản mặc định yield trả về cho bạn kiêu dữ liệu tương ứng với dự liệu trong vòng loop,nếu bạn muốn tìm hiểu kỹ hơn về yield :  yield làm việc như thế nào

OK,hôm nay hơi dài rồi,hẹn gặp lại bạn ngày mai với : Function trong Scala






Comments

  1. hi add, add cho mình cho mình hỏi tại sao mình làm như thế này mà lại báo lỗi chỗ dấu "|":
    caiGiDo match {
    | case kieuSoInt : Int => "đây là kiểu số"
    | case kieuString : String => "đây là kiểu string"
    | case _ => "mệt rồi nên kiểu gì cũng được"
    | }
    res10: String = đây là kiểu số
    tks add

    ReplyDelete
    Replies
    1. bạn cần gửi cụ thể lỗi gì thì mình mới có thể giúp bạn được

      Delete
    2. theo mình phán đoán,bạn đã copy ví dụ và paste thẳng vào scala RELP , thì sẽ bị duplicate 2 dấu ||, bạn có dấu mở ( "{" ) khi gõ enter dấu "|" sẽ được thêm tự động

      Delete
    3. ok, add để mình thử, lúc trước mình gõ cũng như copy nó báo lỗi

      Delete
  2. Anh cho em hỏi là dấu ";" trong đoạn code sau của anh có ý nghĩa như nào ạ

    scala> val tinhTong = {val parent = 1;{val child = parent + 1;child}}
    tinhTong: Int = 2

    ReplyDelete

Post a Comment