2011-09-01 28 views
13

Họ dường như không để trộn mà cũng:Case, phù hợp với mô hình và nhà thầu cà ri trong Scala

abstract class A 
case class B (var a: Int)(var b: String) extends A 
case class C extends A 

Sau đây sẽ không làm việc:

B(1)("1") match { 
    case B(a)(b) => print("B") 
    case C() => print("C") 
} 

Vấn đề là mô hình phù hợp và các đối số bị quấy rầy dường như không hoạt động. Có một cách giải quyết cho điều này?

Trả lời

7

Có vấn đề gì với điều này?

def m(a: A) = a match { 
    case b: B => print("B") 
    case c: C => print("C") 
} 

Tôi chỉ hỏi vì bạn không yêu cầu nhiều chức năng hơn này.

EDIT

này có thể giúp:

object Dog { 
    def apply(name: String)(size: Int) = new Dog(name)(size) 
    def unapply(dog: Dog) = Some(dog.name, dog.size) 
} 
class Dog(val name: String)(var size: Int) 

Bây giờ bạn có thể tạo những con chó hoặc như thế này:

new Dog("Snoopy")(10) 

hay như thế này:

Dog("Snoopy")(10) 

Nhưng khi bạn ghép mẫu trên chó, mẫu xây dựng là không phải là đã quấy lại.

Dog("Snoopy")(10) match { 
    case Dog(a, b) => // do sth with a or b 
} 
+0

Ví dụ đầu tiên của bạn sẽ hoạt động, nhưng tôi sẽ không thể truy cập B.a và B.b trong tuyên bố trường hợp mà không làm một số kiểu chữ xấu xí. Ngoài ra, trong bản chỉnh sửa của bạn, tôi không chắc tôi hiểu tại sao mẫu hàm tạo không bị quấy rầy. Có phải vì không thích hợp? –

+0

Thành thật mà nói tôi không biết tại sao nó hoạt động. Tôi tình cờ gặp nó qua thử và sai. Nó chắc chắn được đề cập ở đâu đó trong đặc tả Scala. Bạn có thể muốn tìm nó nếu nó có liên quan trong trường hợp của bạn. – agilesteel

+1

Có, mẫu bạn sử dụng trong câu lệnh trường hợp là mẫu được đưa ra bởi kết quả của hàm không áp dụng. Nó không bao giờ có thể được curried. Phần tương ứng trong đặc tả scala là §8.1.8 – Nicolas

2

Bạn có thể sử dụng lớp chữ thường và chỉ xác định phương thức nhà máy có nhiều danh sách tham số.

+0

Có thể chúng ta có thể thêm rằng phương thức nhà máy không thể được trích dẫn 'áp dụng' nếu nó được khai báo trong đối tượng đồng hành (vì nó sẽ có cùng một lần xóa e một tuyên bố nhờ vào các trường hợp lớp). – Nicolas

11

Nếu bạn nhìn vào chữ ký của hàm không được tạo cho lớp B, bạn sẽ thấy rằng đó là: unapply(x$0: Q): Option[Int]. Do đó, hàm unapply hoạt động với phạm vi tham số đầu tiên của các lớp chữ hoa chữ thường.

Nó được xác nhận bởi các đặc điểm kỹ thuật scala (§5.3.2):

Các thông số chính thức trong fi tham số đầu tiên phần của một lớp trường hợp được gọi là yếu tố; chúng được xử lý đặc biệt. Đầu tiên, giá trị của một tham số như vậy có thể được trích xuất như một trường của một mẫu hàm tạo.

Nó tuyên bố rõ ràng chỉ tha phần thông số đầu tiên có sẵn thông qua trình ngắt.

Một số cách giải quyết:

  • uncurry thông số của bạn
  • sử dụng một mô hình kết hợp với bảo vệ nếu bạn muốn thử nghiệm 2 giá trị: case [email protected](3) if x.b == "bazinga" => ...
  • sử dụng một lớp bình thường và xác định đối tượng đồng của riêng bạn với bạn của riêng bạn áp dụng/unapply
Các vấn đề liên quan