2011-12-12 18 views
6

tôi xác định một vắt tùy chỉnh để có được những yếu tố cuối cùng của danh sách, như trong https://stackoverflow.com/a/6697749/1092910:trật tự trận đấu với một vắt

object :+ { 
    def unapply[A](l: List[A]): Option[(List[A], A)] = { 
    if (l.isEmpty) 
     None 
    else 
     Some(l.init, l.last) 
    } 
} 

Bây giờ này phù hợp "tốt":

List(1, 2, 3) match { 
    case init :+ last => "good" 
    case head :: tail => "bad" 
} 

Nhưng nếu tôi thêm một mệnh đề khác, nó đột nhiên khớp với "xấu" ngay bây giờ:

List(1, 2, 3) match { 
    case List(7) => "never" 
    case init :+ last => "good" 
    case head :: tail => "bad" 
} 

Lý do cho hành vi này là gì?

+0

Dường như lỗi. Tôi có thể thử hỏi một trong những danh sách gửi thư. – huynhjl

+1

Biên dịch với 'scalac -print', có vẻ như trình biên dịch đang thực hiện một số tối ưu hóa với các mẫu và kết hợp phép thử cho 'List (7)' và 'head :: tail'. đầu tiên nó kiểm tra nếu nó là một danh sách của Int, sau đó kiểm tra nếu phần tử đầu tiên là 7, nếu nó không phải là, nó rơi ngay vào 'đầu :: đuôi' và khớp' đầu :: đuôi'. Điều này có vẻ giống như một lỗi trong trình biên dịch. – markmarch

Trả lời

6

Đó là # 1697/2337 và một tá bản sao.

https://issues.scala-lang.org/browse/SI-1697

Có vẻ an toàn để nói rằng nó sẽ không được cố định trong thời trang trực tiếp, nhưng bằng cách xóa các khớp mẫu để thực hiện virtpatmat. Hãy thử xây dựng và biên dịch gần đây với -Yvirtpatmat, bạn sẽ nhận được câu trả lời đúng.