Kopiowanie moją odpowiedź z listy mailingowej Scala, gdzie została po raz pierwszy zapytał:
Number
jest klasą Java i ma funkcjonalność oprócz przekształcania się do prymitywnych typów. Niestety, Scala's AnyVal
nie robi nic poza zaznaczeniem typów pierwotnych, a Numeric[T]
ze Scala wie tylko o swoim typie, a nie o typie.
Dzięki temu masz dość nieprzyjemne wzorce dopasowania; najkrótsza składnia jeśli jesteś pewien, że masz tylko obsłużyć dwukrotnie i int jest:
list.reduceLeft((l,r) => (l: Any, r: Any) match {
case (li: Int, ri: Int) => li + ri
case _ => l.doubleValue + r.doubleValue
})
Zauważ, że mam do odlewania Any
uzyskać Scala wzór mecz zrobić unboxing dla nas; jeśli zostawisz go jako numer, musisz dopasować wzór na java.lang.Integer
, a następnie valueOf
, co jest uciążliwe.
Jeśli chcesz więcej trzeba będzie zbudować w odpowiednich promocjach:
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. */
})
Jeśli trzeba zrobić więcej niż trochę, jesteś prawdopodobnie lepiej porzucenie Numeric
na rzecz własnego klasy otokowe, które wiedzą, jak dodać siebie wraz z odpowiednią promocją; możesz napisać wzór dopasowujący tylko raz i powrócić do używania + w spisie treści.
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)
...
}
}
...
Jednym niewielkim Zaletą tej metody jest to, że można zdecydować, aby promować wartości w inny sposób niż standardowy (na przykład, może zdecydować, że pływak + długo = podwójne, ponieważ pływak naprawdę nie wyciąć . zachować dużo precyzji numerycznej długo, a zrobić MyDouble(value.toDouble + f.toDouble)
, na przykład
to wszystko jest raczej niewygodne, ani Java ani Scala naprawdę zapewnić wsparcie dla mieszanego typu matematyki
na przyszłość, jest uważana za lepszą formę zapytać. pytanie na liście mailingowej Scala _ lub _ StackOverflow, a nie na oba pytania. lar, StackOverflow jest zwykle lepszym wyborem, ponieważ łatwiej jest innym uczyć się na podstawie pytania i odpowiedzi tutaj, niż na archiwach listy mailingowej! –
Stoję poprawione. To nie zdarzy się ponownie. Dziękuję za całą pomoc i za tak delikatne uczenie mnie netykiety. – Andres