Toán tử Scala @


Câu trả lời:


179

Nó cho phép một người liên kết một mô hình phù hợp với một biến. Hãy xem xét những điều sau đây, ví dụ:

val o: Option[Int] = Some(2)

Bạn có thể dễ dàng trích xuất nội dung:

o match {
  case Some(x) => println(x)
  case None =>
}

Nhưng nếu bạn muốn không phải là nội dung của Some, nhưng tùy chọn riêng của mình? Điều đó sẽ được thực hiện với điều này:

o match {
  case x @ Some(_) => println(x)
  case None =>
}

Lưu ý rằng @có thể được sử dụng ở mọi cấp độ, không chỉ ở cấp cao nhất của kết hợp.


5
Trường hợp trong tài liệu tôi sẽ tìm thấy câu trả lời? Tôi có cảm giác có những thứ tốt khác cũng được chôn ở đó. :)
Jim Barrow

1
@ Tham khảo Scala, 8.1. 8.12, cụ thể, mặc dù tôi không biết "như thường lệ" đến từ đâu - và 8.12 chỉ nói về mẫu biểu thức chính quy ( _*). Nhưng có lẽ điều này đã được làm rõ trên một phiên bản mới hơn của thông số kỹ thuật.
Daniel C. Sobral

16
Tôi sẽ thêm rằng bạn có thể sẽ không sử dụng @với Some(_), nhưng thay vào đó nếu bạn muốn khớp với nội dung của Some, nhưng vẫn đề cập đến chính Một số, ví dụ case x @ Some(7) => println(x). Theo tôi giải thích, nó case x @ Some(_)chỉ là một phiên bản dài dòng hơn case x: Some.
Theo

2
Điều này cũng được đề cập trong phần "Liên kết biến" trong Phần 15.2 của "Lập trình trong Scala - Phiên bản 2" và được sử dụng lại trong phần 26.3 (chương về trình trích xuất).
Shaun the Sheep

@Theo case x: Somekhông tự làm việc. Bạn phải sử dụng case x: Some[_], không kém phần dài dòng
Luigi Plinge

74

@có thể được sử dụng để liên kết một tên với một mẫu phù hợp thành công hoặc mô hình con. Các mẫu có thể được sử dụng trong khớp mẫu, phía bên trái của <-in để hiểu và phá hủy các giả định.

scala> val d@(c@Some(a), Some(b)) = (Some(1), Some(2))
d: (Some[Int], Some[Int]) = (Some(1),Some(2))
c: Some[Int] = Some(1)
a: Int = 1
b: Int = 2

scala> (Some(1), Some(2)) match { case d@(c@Some(a), Some(b)) => println(a, b, c, d) }
(1,2,Some(1),(Some(1),Some(2)))

scala> for (x@Some(y) <- Seq(None, Some(1))) println(x, y)
(Some(1),1)

scala> val List(x, xs @ _*) = List(1, 2, 3) 
x: Int = 1
xs: Seq[Int] = List(2, 3)

10

Khi khớp mẫu variable @ patternliên kết biến với giá trị khớp với mẫu nếu mẫu khớp. Trong trường hợp này có nghĩa là giá trị của xsẽ nằm Some(Nil)trong mệnh đề trường hợp đó.


9

Cho phép bạn khớp mức cao nhất của mẫu. Thí dụ:

case x @ "three" => assert(x.equals("three"))
case x @ Some("three") => assert(x.get.equals("three")))
case x @ List("one", "two", "three") => for (element <- x) { println(element) }

6
Không chỉ cấp cao nhất.
Daniel C. Sobral

2

Nó đặt giá trị của xmẫu phù hợp. Trong ví dụ của bạn, xdo đó sẽ là Some(Nil)(như bạn có thể xác định từ một cuộc gọi đến println )


1
Chết tiệt, iPhone không có khả năng hiển thị backtick!
oxbow_lakes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.