tại sao chính xác hiện Scala trình biên dịch không phát nổ với lỗi?
Vì sự cố này không thể giải quyết được trong trường hợp chung. Bạn có biết số halting problem không? Các vấn đề dừng lại nói rằng nó không thể viết một thuật toán mà phát hiện ra nếu một chương trình bao giờ dừng lại. Kể từ khi vấn đề tìm ra nếu một định nghĩa đệ quy sẽ dẫn đến một chuyển nhượng null có thể được giảm đến vấn đề dừng, nó cũng không thể giải quyết nó.
Vâng, bây giờ nó là khá dễ dàng để cấm các định nghĩa đệ quy ở tất cả, đây là ví dụ làm cho các giá trị mà không có giá trị lớp:
scala> def f = { val k: String = k+"abc" }
<console>:11: error: forward reference extends over definition of value k
def f = { val k: String = k+"abc" }
^
Đối với giá trị đẳng cấp tính năng này không cấm đối với một vài lý do :
- phạm vi của họ là không giới hạn
- Các JVM khởi chúng với giá trị mặc định (mà là null với nhiều loại tài liệu tham khảo).
- giá trị Đệ quy là hữu ích
trường hợp sử dụng của bạn là tầm thường, như là thế này:
scala> val k: String = k+"abc"
k: String = nullabc
Nhưng những gì về vấn đề này:
scala> object X { val x: Int = Y.y+1 }; object Y { val y: Int = X.x+1 }
defined object X
defined object Y
scala> X.x
res2: Int = 2
scala> Y.y
res3: Int = 1
scala> object X { val x: Int = Y.y+1 }; object Y { val y: Int = X.x+1 }
defined object X
defined object Y
scala> Y.y
res4: Int = 2
scala> X.x
res5: Int = 1
Hoặc này:
scala> val f: Stream[BigInt] = 1 #:: 1 #:: f.zip(f.tail).map { case (a,b) => a+b }
f: Stream[BigInt] = Stream(1, ?)
scala> f.take(10).toList
res7: List[BigInt] = List(1, 1, 2, 3, 5, 8, 13, 21, 34, 55)
Như bạn có thể thấy nó khá dễ dàng để viết các chương trình mà nó không còn rõ ràng nữa với giá trị mà chúng sẽ tạo ra. Và kể từ khi vấn đề dừng lại không thể giải quyết được, chúng tôi không thể để trình biên dịch thực hiện công việc cho chúng tôi trong các trường hợp không tầm thường.
Điều này cũng có nghĩa là các trường hợp tầm thường, như trường hợp được hiển thị trong câu hỏi của bạn, có thể được mã hóa cứng trong trình biên dịch. Nhưng vì không thể tồn tại một thuật toán có thể phát hiện tất cả các trường hợp tầm thường, tất cả các trường hợp được tìm thấy cần phải được mã hóa cứng trong trình biên dịch (chưa kể rằng định nghĩa của một trường hợp tầm thường không tồn tại). Vì vậy nó sẽ không được khôn ngoan để thậm chí bắt đầu hardcoding một số trường hợp này. Cuối cùng nó sẽ dẫn đến trình biên dịch chậm hơn và trình biên dịch khó bảo trì hơn.
Người ta có thể lập luận rằng đối với một trường hợp sử dụng có thể đốt cháy mọi người dùng thứ hai, thì ít nhất cũng nên mã hóa một kịch bản cực đoan như vậy. Mặt khác, một số người chỉ cần bị đốt cháy để học cái gì đó mới. ;)
trong Scala 2.11.4 Tôi chiến tranh ning 'warning: value name trong đối tượng WTF không có gì khác hơn là gọi chính nó đệ quy val name: String = name' – Brian
Tôi đang sử dụng Scala 2.11.7, và tôi không nhận được thông báo đó và không có đệ quy vì nó là một val: bạn có chắc bạn không sử dụng * def *? Ngoài ra, bạn có đang chạy nó từ dòng lệnh hoặc trình thông dịch không ??? Tôi đang sử dụng Intellij –
Tôi chỉ nhận thấy rằng nó không thành công trong REPL với thông báo sau .. scala> val o: String = o: 8: cảnh báo: giá trị o không có gì khác hơn là gọi chính nó đệ quy –