2010-03-19 23 views
24

Theo như tôi hiểu, Scala == xác định sự bình đẳng tự nhiên của hai đối tượng.Tại sao `Mảng (0,1,2) == Mảng (0,1,2)` không trả về kết quả mong đợi?

Tôi mong đợi rằng Array(0,1,2) == Array(0,1,2) so sánh bình đẳng tự nhiên. Ví dụ, kiểm tra xem tất cả các phần tử của mảng có trả về true khi so sánh với các phần tử tương ứng của mảng khác không.

Mọi người nói với tôi rằng Scala's Array chỉ là một Java [] chỉ so sánh danh tính. Nó sẽ không có ý nghĩa hơn khi ghi đè lên phương pháp equals của phương pháp Array để so sánh bình đẳng tự nhiên?

+0

Tôi không quen với Scala. Tuy nhiên, bạn có chắc chắn == không so sánh xem các mảng có phải là các bí danh (tham chiếu tới cùng một đối tượng trong bộ nhớ) không? Tôi giả định đây là một khả năng, vì bạn đã đề cập nó có liên quan đến một mảng Java. – Cam

+1

Đó là một tình huống không may, như các câu trả lời khác mô tả, nhưng khi bạn biết bạn đang đối phó với Array, bạn có thể sử dụng sameElements và nhận được câu trả lời bạn muốn trong khi tránh tất cả các gói và boxing và circumlocutions. –

Trả lời

19

Scala 2.7 đã cố thêm chức năng vào các mảng Java [] và chạy vào các trường hợp góc có vấn đề. Scala 2.8 đã tuyên bố rằng Array[T]T[], nhưng nó cung cấp trình bao bọc và tương đương.

Hãy thử như sau trong 2.8 (chỉnh sửa/lưu ý: tính RC3, GenericArrayArraySeq --thanks để retronym cho trỏ này ra):

import scala.collection.mutable.{GenericArray=>GArray, WrappedArray=>WArray} 
scala> GArray(0,1,2) == GArray(0,1,2) 
res0: Boolean = true 

scala> (Array(0,1,2):WArray[Int]) == (Array(0,1,2):WArray[Int]) 
res1: Boolean = true 

GenericArray hành vi giống như Array, trừ trường hợp được tất cả các Scala bộ sưu tập goodies được thêm vào. WrappedArray kết thúc tốt đẹp Java [] mảng; ở trên, tôi đã đúc một mảng đơn giản với nó (dễ hơn gọi hàm chuyển đổi ngầm) và sau đó so sánh các mảng được bao bọc. Những trình bao bọc này, mặc dù được hỗ trợ bởi mảng [], cũng cung cấp cho bạn tất cả các tính năng sưu tập.

+0

Có bất kỳ hiệu suất/bộ nhớ/đánh máy/... lợi ích nào từ việc sử dụng các lớp này thay vì e. g. một danh sách sau đó? Tôi có thể tưởng tượng rằng GenericArray/WrappedArray thêm khá một chút chi phí ... – soc

+1

Không, thực sự, họ thêm rất ít chi phí - 'WrappedArray' là một lớp thêm bọc xung quanh một mảng Java đồng bằng. 'Danh sách' yêu cầu một lớp phụ xung quanh _every đơn element_. Bạn sử dụng danh sách vì dễ sử dụng và phù hợp với mô hình mát mẻ và bất biến, không phải cho hiệu quả. 'GenericArray' có một vị trí hơi kỳ lạ, mặc dù, là một mảng có kích thước cố định: kích thước là không thay đổi nhưng nội dung có thể thay đổi được.Tại sao, người ta có thể tự hỏi, không chỉ sử dụng một 'ArrayBuffer'? –

+1

Bạn có thể sử dụng danh sách không thay đổi vì hiệu suất. Các bộ sưu tập không thể thay đổi có thể giúp bạn tránh phải tạo ra các bản sao phòng thủ. Tùy thuộc vào ứng dụng này có thể lớn hơn chi phí của họ. – ziggystar

5

Nhưng chuỗi của Scala cũng chỉ là một Java Chuỗi nhưng ghi đè Scala bằng so sánh bình đẳng tự nhiên.

Scala không ghi đè bất kỳ thứ gì ở đó; java.lang.String có thực hiện phụ thuộc giá trị equals() (giống như nhiều lớp Java khác, nhưng không giống như mảng).

+0

Xin chào Michael, cảm ơn! Tôi đã sửa câu hỏi của mình cho phù hợp. Về cơ bản, tôi chỉ tự hỏi tại sao bằng không được ghi đè để trả lại bình đẳng tự nhiên như các lớp Collection (tôi biết rằng Array không thuộc về các lớp Collection!). – soc

+3

Scala diễn giải '==' bằng 'bằng'. Đó là tất cả. 'Chuỗi' có một' bằng 'làm một cái gì đó khác biệt với danh tính tham chiếu. '[]' thì không. –

8

Scala không ghi đè lên sự bình đẳng của Array vì không thể thực hiện được. Người ta chỉ có thể ghi đè lên các phương thức khi phân lớp. Vì Array không được phân lớp (điều này là không thể), Scala không thể ghi đè lên các phương thức của nó.

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