Sao chép câu trả lời của tôi từ mailing list Scala nơi câu hỏi lần đầu tiên được hỏi:
Number
là một lớp Java, và không có chức năng ngoài việc chuyển đổi bản thân để loại nguyên thủy. Thật không may, Scala của AnyVal
không làm bất cứ điều gì ngoài việc đánh dấu các loại nguyên thủy, và Numeric[T]
từ Scala chỉ biết về loại riêng của nó, không phải là một kết hợp của các loại.
Vì vậy, bạn đã để lại kết hợp mẫu tương đối khó chịu; cú pháp ngắn nhất nếu bạn chắc chắn bạn chỉ cần xử lý gấp đôi và int là:
list.reduceLeft((l,r) => (l: Any, r: Any) match {
case (li: Int, ri: Int) => li + ri
case _ => l.doubleValue + r.doubleValue
})
Lưu ý rằng tôi đúc để Any
để có được những mô hình phù hợp Scala để làm unboxing cho chúng ta; nếu bạn để nó như là Số, bạn phải kết hợp mẫu trên java.lang.Integer
và sau đó valueOf
nó, đó là một nỗi đau.
Nếu bạn muốn biết thêm bạn sẽ phải xây dựng trong chương trình khuyến mãi phù hợp:
list.reduceLeft((l,r) => (l: Any) match {
case li: Int => (r: Any) match {
case ri: Int => li + ri
case rf: Float => li + rf
case rl: Long => li + rl
case _ => li + r.doubleValue
}
case lf: Float => /* etc. */
})
Nếu bạn phải làm điều này hơn một chút, bạn có lẽ tốt hơn bỏ Numeric
ủng hộ của riêng bạn các lớp bao bọc mà biết cách thêm chính mình cùng với quảng cáo phù hợp; sau đó bạn có thể viết mẫu phù hợp với chỉ một lần và quay trở lại sử dụng + trong danh sách của bạn comprehensions.
sealed abstract class Addable {
def +(a: Addable): Addable
}
final case class MyInt(value: Int) extends Addable {
def +(a: Addable) = a match {
case MyInt(i) => MyInt(value + i)
case MyFloat(f) => MyFloat(value + f)
...
}
}
final case class MyFloat(value: Float) extends Addable {
def +(a: Addable) = a match {
case MyInt(i) => MyFloat(value + i)
...
}
}
...
Một ưu điểm nhẹ của phương pháp này là bạn có thể quyết định để phát huy giá trị một cách khác so với tiêu chuẩn (ví dụ, bạn có thể quyết định rằng phao + dài = đôi, từ một phao thực sự không được cắt ra . để giữ phần lớn chính xác số dài, và làm MyDouble(value.toDouble + f.toDouble)
, ví dụ
đó là tất cả khá vụng về; không phải Java cũng không Scala thực sự cung cấp hỗ trợ cho hỗn hợp kiểu toán học
để tham khảo trong tương lai, nó được coi là hình thức tốt hơn để hỏi. một câu hỏi _either_ trên danh sách gửi thư của Scala _or_ StackOverflow, không phải cả hai. Đối với các câu hỏi như thế này trong đặc biệt lar, StackOverflow thường là sự lựa chọn tốt hơn, vì nó dễ dàng hơn cho những người khác học hỏi từ câu hỏi và câu trả lời ở đây hơn là trên lưu trữ danh sách gửi thư! –
Tôi đã sửa chữa. Nó sẽ không xảy ra nữa đâu. Cảm ơn tất cả sự giúp đỡ và vì đã nhẹ nhàng trong việc dạy tôi netiquette. – Andres