Như chúng ta biết, chúng ta có thể thêm (trừ/nhân/etc) hai số khác nhau Numeric
và kết quả sẽ rộng hơn trong hai loại, bất kể thứ tự của chúng.tham số kiểu và mở rộng số
33F + 9L // Float + Long == Float
33L + 9F // Long + Float == Float
Điều này là do mỗi người trong số 7 Numeric
lớp (Byte
, Short
, Char
, Int
, Long
, Float
, Double
) có 7 +()
phương pháp khác nhau (và -()
, *()
, vv), một cho mỗi Numeric
loại có thể nhận được dưới dạng tham số được truyền. [Có một +()
phương pháp phụ để xử lý một tham số String
, nhưng điều đó không nhất thiết liên quan đến chúng tôi ở đây.]
Bây giờ xem xét như sau:
implicit class PlusOrMinus[T: Numeric](a: T) {
import Numeric.Implicits._
def +-(b: T) = if (util.Random.nextBoolean) a+b else a-b
}
này hoạt động nếu hai toán hạng là cùng loại, nhưng nó cũng hoạt động nếu loại toán hạng 1 rộng hơn loại thứ hai.
11F +- 2L // result: Float = 9.0 or 13.0
Tôi tin rằng những gì đang xảy ra ở đây là trình biên dịch sử dụng weak conformance để đạt numeric widening trên các toán hạng thứ 2 (tham số b
) vì nó được truyền cho phương thức +-()
.
Nhưng toán hạng 1 sẽ không được mở rộng để khớp với số thứ hai. Nó thậm chí sẽ không biên dịch.
11L +- 2F // Error: type mismatch; found: Float(2.0) required: Long
Có cách nào xung quanh giới hạn này không?
Tôi không thể sử dụng thông số loại khác cho đối số b
(def +-[U: Numeric](b: U) = ...
) vì một Numeric
, được biểu thị qua thông số loại, chỉ có thể cộng/trừ loại riêng của nó.
Là giải pháp duy nhất để tạo 7 lớp khác nhau (PlusOrMinusShort/Int/Long/
, v.v.) với 7 phương pháp khác nhau (def +-(b:Short)
, def +-(b:Int)
, def +-(b:Long)
, v.v ...)?