2010-06-24 3 views
55

Tôi đang khám phá ngôn ngữ Scala. Một tuyên bố mà tôi thường nghe là Scala có hệ thống loại mạnh mẽ hơn so với Java. Bằng cách này, tôi nghĩ rằng những gì mọi người có nghĩa là:Ưu điểm của hệ thống kiểu Scala

  • scalac bác bỏ các chương trình lỗi nào đó mà javac sẽ biên dịch vui vẻ, chỉ để gây ra một lỗi thời gian chạy.
  • Một số bất biến có thể được mã hóa trong chương trình Scala sao cho trình biên dịch sẽ không cho phép lập trình viên viết mã vi phạm điều kiện.

Tôi có đang suy nghĩ như vậy không? Nếu có, vui lòng trỏ đến các bài viết/blog/giấy tờ minh họa các ví dụ như vậy.

+4

Java sẽ không cho phép bạn biên dịch "các chương trình lỗi" hơn bất kỳ Scala nào; tuy nhiên, Scala * cho phép * nhiều cấu trúc hơn được [an toàn] thể hiện - và nói chung trong một phương thức dễ dàng hơn nhiều - hơn Java. Tuy nhiên, Scala vẫn "bị" từ loại tẩy xóa. –

+15

@pst: Có, nó sẽ. Chuỗi 'String [] = {" foo "}; Đối tượng [] đối tượng = chuỗi; object [0] = new Object(); 'sẽ biên dịch tốt trong java và sau đó ném NPE vào thời gian chạy. Mã scala tương đương sẽ không biên dịch. – sepp2k

+5

@ sepp2k Tôi nghĩ rằng đó là một 'ArrayStoreException' được ném ra, không phải là một NPE. –

Trả lời

72

Ưu điểm chính của hệ thống Loại Scala không phải là quá nhiều thời gian dành mạnh nhưng khá là xa giàu (xem "The Scala Type System").
(Java có thể xác định một số người trong số họ và triển khai những người khác, nhưng Scala đã tích hợp sẵn).
Xem thêm The Myth Makers 1: Scala's "Type Types", nhận xét Steve Yegge's blog post, nơi ông "giải tán" Scala là "Quái vật của Frankenstein" vì "có loại loại và loại loại".

  • Loại giá trị (hữu ích cho các cấu trúc dữ liệu hợp lý có giá trị ngữ nghĩa) được sử dụng thay cho các loại nguyên thủy (Int, Doubles, ...), với chuyển đổi ẩn sang lớp "Rich".
  • Nonnullable type
  • Monad types
  • loại Trait (và mixin composition mà đi kèm với nó)
  • loại đối tượng Singleton (chỉ cần xác định một 'đối tượng' và bạn có một),
  • Compound types (nút giao thông của các loại đối tượng , để thể hiện rằng loại đối tượng là loại phụ của một số loại khác),
  • Functional types ((type1, …)=>returnType cú pháp),
  • Case classes (lớp thường xuyên trong đó xuất khẩu thông số nhà xây dựng của họ và cung cấp một cơ chế phân hủy đệ quy qua mô hình kết hợp),
  • Path-dependent types (Ngôn ngữ cho phép bạn loại tổ cung cấp cách để chỉ những con đường type),
  • Anonymous types (để xác định vô danh chức năng),
  • Self types (có thể used for instance in Trait),
  • Type aliases, cùng với:
  • package object (giới thiệu trong 2,8)
  • Generic types (như Java), với một type parameter annotation mechanism để kiểm soát hành vi subtyping các loại chung chung,
    • kiểu generic hiệp biến: Chú thích +T tuyên bố gõ T chỉ được sử dụng ở các vị trí hiệp biến. Stack[T] là một loại phụ của Stack[S] nếu T là một loại phụ của S.
    • Các loại chung chung biến thể: -T sẽ khai báo T chỉ được sử dụng ở các vị trí khắc phục.
  • loại giáp generic (mặc dù Java supports some part of it),
  • Higher kinded types, cho phép một để diễn tả mối quan hệ loại tiên tiến hơn là có thể với Java Generics,
  • Abstract types (thay thế cho loại generic),
  • Existential types (sử dụng in Scala như kiểu ký tự đại diện Java),
  • Implicit types (xem "The awesomeness of Scala is implicit",
  • View bounded types
  • Structural types, để chỉ định loại bằng cách chỉ định đặc điểm của loại mong muốn (nhập vịt).
+0

Cảm ơn bạn đã viết chi tiết. Tôi sẽ đọc các bài báo được liên kết để hiểu rõ hơn. –

+1

Lưu ý về bản thân: xem thêm câu trả lời cũ của tôi http://stackoverflow.com/questions/2682673/what-compromises-scala-made-to-run-on-jvm/2682962#2682962 – VonC

+1

Lưu ý đến bản thân: với tiềm ẩn và bối cảnh 2.8 mới bị ràng buộc, mẫu như "Loại Lớp" dễ dàng được xác định và sử dụng: http://dcsobral.blogspot.com/2010/06/implicit-tricks-type-class-pattern.html – VonC

14

Vấn đề an toàn chính với Java liên quan đến phương sai. Về cơ bản, một lập trình viên có thể sử dụng các khai báo phương sai không chính xác có thể dẫn đến các ngoại lệ được ném vào thời gian chạy trong Java, trong khi Scala sẽ không cho phép nó.

Trên thực tế, thực tế là số Array của Java là một vấn đề, vì nó cho phép tạo mã không chính xác. Ví dụ, như được minh họa bởi sepp2k:

String[] strings = {"foo"}; 
Object[] objects = strings; 
objects[0] = new Object(); 

Sau đó, tất nhiên, có nhiều loại nguyên liệu trong Java, cho phép tất cả các loại của sự vật.

Ngoài ra, mặc dù Scala có nó là tốt, có đúc. Java API có nhiều loại phôi, và không có thành ngữ nào giống như của Scala là case x: X => // x is now safely cast. Chắc chắn, một trường hợp sử dụng instanceof để thực hiện điều đó, nhưng không có động cơ để làm điều đó. Trên thực tế, số asInstanceOf của Scala được cố ý tiết lộ.

Đây là những điều làm cho hệ thống kiểu của Scala mạnh mẽ hơn. Nó cũng phong phú hơn nhiều, như VonC hiển thị.

+0

Cuối cùng, một câu trả lời có nhiều "về chủ đề" hơn danh sách "tổng quát hơn" của tôi;) +1 – VonC

+0

bạn đã trả lời câu hỏi gốc chính xác, nhưng VonC đã trả lời một câu hỏi hơi khác một cách công phu. Tôi đang bỏ phiếu cho câu trả lời của anh ấy là câu trả lời đúng, nhưng câu trả lời của bạn cũng được đánh giá cao. Hy vọng bạn không nhớ mất tích trên các điểm danh tiếng. –

+0

@binil Không hề. Câu trả lời của VonC là tuyệt vời, ngay cả khi anh ấy thực sự không cần thêm danh tiếng ... ;-) –