2016-03-19 19 views
8

Trong khi học scala tôi stumbled khi đoạn lạ sau:Scala không đưa ra lỗi biên dịch khi gán giá trị cho một chữ số?

package temptests 

object TempTest { 
    //def 2 = 123 // does not compile 
    val 2 = 123 // compiles, but leads to an exception at runtime 

    def main(args: Array[String]) = { // just do something to load this class 
    println("Hello") 
    } 
} 

Tôi mong rằng trình biên dịch sẽ ném một lỗi trên val 2 = 123 vì định danh không phải bắt đầu bằng một chữ số, nhưng mã biên dịch mà không có một cảnh báo. Tuy nhiên, khi chạy nó ngay lập tức ném một ngoại lệ:

Exception in thread "main" java.lang.ExceptionInInitializerError at temptests.TempTest.main(TempTest.scala) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) Caused by: scala.MatchError: 123 (of class java.lang.Integer) at temptests.TempTest$.(TempTest.scala:5) at temptests.TempTest$.(TempTest.scala) ... 6 more

Tôi chỉ tò mò: làm thế nào được val 2 = 123 hiểu bởi Scala? Tại sao không có lỗi biên dịch?

+0

Tôi chắc chắn 100% đây là một bản sao, nhưng tôi không thể cho cuộc sống của tôi tìm thấy một! –

Trả lời

12

I am just curious: how is val 2 = 123 understood by Scala?

Bạn có thể nghĩ val 2 = 123 như:

123 match { 
    case 2 => 2 
} 

Tên phần biến trong Scala không phải là luôn luôn là một tên đơn giản, nó cũng có thể là một mô hình , ví dụ:

val (x, y) = (1, 2) 

Sẽ phân hủy 1 và 2 thành x và y tương ứng. Trong scala, mọi thứ được cho phép sau tuyên bố trường hợp cũng được phép sau val và được dịch sang đối sánh mẫu.

From the specification (tôi nhấn mạnh):

Value definitions can alternatively have a pattern as left-hand side. If p is some pattern other than a simple name or a name followed by a colon and a type, then the value definition val p = e is expanded as follows:

(Bỏ qua để ví dụ có liên quan):

If p has a unique bound variable x:

val x = e match { case p => x } 

Đây là lý do trình biên dịch không phát ra một lỗi thời gian biên dịch. Có một cuộc thảo luận dài về chủ đề trong số google group question này.

+0

Tôi nghĩ rằng trận đấu phải là một cách khác xung quanh là '2' là mẫu phù hợp. –

+0

Nhờ cả hai bạn! Điều này cũng cho thấy lý do tại sao 'val 2 = 2' hoạt động mà không có vấn đề gì. Tuy nhiên, có * bất kỳ * ví dụ nào trong đó hữu ích để có ở phía bên trái một chữ chứ không phải là một mô hình tổng quát hơn? –

+0

@cubiclettuce Không thể nghĩ ra lý do bạn thực sự muốn * làm điều đó. –

3

Phía bên trái của tuyên bố val có thể là mẫu. Xem scala language documentation.

nên

val 2 = 123 

có thể được viết như

123 match { 
    case 2 => 2 
} 

mà đưa ra một lỗi trận đấu.

Trong cuộc sống thực này chủ yếu được sử dụng để trích xuất các bộ để Vals readably địa phương:

val test = ("Foo", 30) 
val (name, age) = test 
Các vấn đề liên quan