2010-04-16 31 views
8

Xin chào đồng Scala Các lập trình viênScala mẫu sẽ không phù hợp với java.lang.String và trường hợp lớp

Tôi đã làm việc với Scala đối với một số tháng nay, tuy nhiên tôi có một vấn đề với một số nội dung cơ bản đúng, tôi hy vọng bạn sẽ giúp tôi với nó.

case class PersonClass(name: String, age: Int) 

object CaseTester { 
def main(args:Array[String]) 
{ 
    val string = "hej" 
    string match { 
    case e:String => println(string) 
    case PersonClass => println(string) 
    } 
} 
} 

Khi tôi đang làm như thế này tôi nhận được lỗi:

pattern type is incompatible with expected type; 
found : object PersonClass 
required: java.lang.String 
case PersonClass => println(string) 

Và nếu tôi sau đó thay đổi dòng thứ hai trong mô hình phù hợp với những điều sau đây:

case e:PersonClass => println(string) 

sau đó tôi nhận được lỗi:

error: scrutinee is incompatible with pattern type; 
found : PersonClass 
required: java.lang.String 
case e:PersonClass => println(string) 

Tuy nhiên nếu tôi thay đổi định nghĩa chuỗi sau đây, nó biên dịch tốt trong cả hai trường hợp.

val string:AnyRef = "hej" 
+0

Ban đầu tôi đã gặp sự cố khi cố tạo lớp vỏ cũng có thể là trình trích xuất, tuy nhiên khi tôi nghĩ về nó không có ý nghĩa gì nhiều :) – Stefan

+0

Bạn không thể khớp với lớp học như thế. 'case PersonClass =>' chỉ hoạt động nếu 'PersonClass' là một đối tượng. Để kết hợp các lớp, bạn hoặc gán cho một biến cục bộ: 'case e: String =>' hoặc giải nén nếu nó là một tuple hoặc case case: '(3, 4) match {case (a, b) =>' – Ryan

Trả lời

21

Loại suy luận của chuỗi là Chuỗi. Điều đó được biết đến sau khi khai báo val.

Như chúng ta đã biết trong quá trình so khớp mẫu, không phù hợp với các mẫu không phải là Strings (giống như PersonClass) vì chúng sẽ không bao giờ khớp nhau. Đó là những gì "kiểu mẫu không tương thích với kiểu mong đợi; tìm thấy: đối tượng PersonClass yêu cầu: java.lang.String trường hợp PersonClass => println (string)" lỗi có nghĩa là: chúng ta mong đợi một mẫu là một phân lớp của String, nhưng tìm thấy một cái gì đó (PersonClass) mà không phải là.

Khi bạn buộc loại AnyRef, thay đổi tình hình. Trình biên dịch sẽ xử lý chuỗi như Anyref, vì vậy các mẫu mở rộng AnyRef có thể phù hợp. PersonClass là AnyRef, do đó bạn không gặp lỗi.

8

Nếu bạn đã có đối tượng kiểu String, nó sẽ không bao giờ khớp với loại PersonClass. Nó thực sự là một tính năng mà trình biên dịch bạn không cho phép làm những trận đấu đó sẽ không bao giờ thành công.

Với loại Bất kỳ, bạn chỉ cần tắt chế độ kiểm tra loại. Nó sẽ không phù hợp với định nghĩa này nhưng trình biên dịch không thể bắt được vấn đề này.

5

Tôi cho rằng bạn đang thử nghiệm một thứ khác, nhưng trình biên dịch quá thông minh để cho phép bạn.

Có lẽ bạn muốn một cái gì đó như thế này:

object Test { 
    case class Person(name: String, age: Int) { } 
    def myPrint(ar: AnyRef) { 
    ar match { 
     case s: String => println(s) 
     case Person(name, age) => println("My name is "+name) 
     case _ => println("I am a mystery!") 
    } 
    } 
    def test = { 
    myPrint("Hello, World") 
    myPrint(Person("John Doe",40)) 
    myPrint(5) 
    } 
} 

nhưng như những người khác đã chỉ ra, nếu bạn không thực sự cần phải kiểm tra đối với các loại khác, trình biên dịch sẽ phàn nàn rằng những gì bạn đang làm là vô nghĩa. Một điều tốt nữa: nếu bạn không viết một bài kiểm tra, bạn có thể gặp lỗi thời gian chạy khó gỡ lỗi.

0
object ws { 

case class PersonClass(name:String,age: Int) 
val p=new PersonClass("ach",25)      

    def string(x: Any) = x match { 
    case x:String => println(x) 
    case x:PersonClass => println(p.name +" "+p.age) 
    }            

    string("aa")         //> aa 
    string(p)         //> ach 25 

} 
Các vấn đề liên quan