Scala - Bộ chiết

Một trình giải nén trong Scala là một đối tượng có một phương thức được gọi là unapplylà một trong những thành viên của nó. Mục đích của phương thức không được áp dụng đó là so khớp một giá trị và tách nó ra. Thông thường, đối tượng trích xuất cũng xác định một phương thức képapply để xây dựng các giá trị, nhưng điều này không bắt buộc.

Thí dụ

Chúng ta hãy lấy một ví dụ về đối tượng xác định cả hai applyunapplycác phương pháp. Phương thức áp dụng có ý nghĩa giống như mọi khi: nó biến Kiểm thử thành một đối tượng có thể được áp dụng cho các đối số trong dấu ngoặc đơn giống như cách một phương thức được áp dụng. Vì vậy, bạn có thể viết Test ("Zara", "gmail.com") để xây dựng chuỗi "[email protected]".

Các unapply phương thức là thứ biến lớp Kiểm tra thành một extractor và nó đảo ngược quá trình xây dựng apply. Trường hợp áp dụng lấy hai chuỗi và tạo thành một chuỗi địa chỉ email từ chúng, không đăng ký lấy một địa chỉ email và trả về hai chuỗi có khả năng:userdomain của địa chỉ.

Các unapplycũng phải xử lý trường hợp chuỗi đã cho không phải là địa chỉ email. Đó là lý do tại sao không áp dụng trả về kiểu Tùy chọn trên các cặp chuỗi. Kết quả của nó làSome (user, domain)nếu chuỗi str là địa chỉ email với người dùng và phần miền đã cho hoặc Không có, nếu str không phải là địa chỉ email. Dưới đây là một số ví dụ như sau.

Cú pháp

unapply("[email protected]") equals Some("Zara", "gmail.com")
unapply("Zara Ali") equals None

Chương trình ví dụ sau hiển thị một đối tượng trích xuất cho các địa chỉ email.

Thí dụ

object Demo {
   def main(args: Array[String]) {
      println ("Apply method : " + apply("Zara", "gmail.com"));
      println ("Unapply method : " + unapply("[email protected]"));
      println ("Unapply method : " + unapply("Zara Ali"));
   }
   
   // The injection method (optional)
   def apply(user: String, domain: String) = {
      user +"@"+ domain
   }

   // The extraction method (mandatory)
   def unapply(str: String): Option[(String, String)] = {
      val parts = str split "@"
      
      if (parts.length == 2){
         Some(parts(0), parts(1)) 
      } else {
         None
      }
   }
}

Lưu chương trình trên vào Demo.scala. Các lệnh sau được sử dụng để biên dịch và thực thi chương trình này.

Chỉ huy

\>scalac Demo.scala
\>scala Demo

Đầu ra

Apply method : [email protected]
Unapply method : Some((Zara,gmail.com))
Unapply method : None

Phù hợp với mẫu với bộ chiết

Khi một thể hiện của một lớp được theo sau bởi dấu ngoặc đơn với danh sách không hoặc nhiều tham số, trình biên dịch sẽ gọi applytrên trường hợp đó. Chúng ta có thể định nghĩa áp dụng cả trong các đối tượng và trong các lớp.

Như đã đề cập ở trên, mục đích của unapplyphương pháp là trích xuất một giá trị cụ thể mà chúng tôi đang tìm kiếm. Nó hoạt động ngược lạiapplylàm. Khi so sánh một đối tượng trích xuất bằng cách sử dụngmatch tuyên bố unapply phương thức sẽ được tự động thực thi.

Hãy thử chương trình ví dụ sau.

Thí dụ

object Demo {
   def main(args: Array[String]) {
      val x = Demo(5)
      println(x)

      x match {
         case Demo(num) => println(x+" is bigger two times than "+num)
         
         //unapply is invoked
         case _ => println("i cannot calculate")
      }
   }
   def apply(x: Int) = x*2
   def unapply(z: Int): Option[Int] = if (z%2==0) Some(z/2) else None
}

Lưu chương trình trên vào Demo.scala. Các lệnh sau được sử dụng để biên dịch và thực thi chương trình này.

Chỉ huy

\>scalac Demo.scala
\>scala Demo

Đầu ra

10
10 is bigger two times than 5