ok super dumb question - why is the type system an...
# getting-started
d
ok super dumb question - why is the type system angry?
Copy code
val sides = arrayOf<Number>(1,2,3)
        val sum = sides[0] + sides[1]
// Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [...much detail]
e
there are no arithmetic operations on generic
Number
, only on concrete subtypes
b
You could also just use arrayOf(1,2,3) and let the type be automatically determined. In this case it will be an Array<Int>
e
intArrayOf(1, 2, 3)
will result in a primitive
IntArray
👍 1
d
roger, thanks, makes sense.
tricky bit for me now is I’ve inherited this constructor type signature from the Exercism problem boilerplate
Triangle<out T : Number>(val a: T, val b: T, val c: T)
and I need to find a way to coax T into something concrete I can add up … helicopter dogging:
val sides = arrayOf(a,b,c) as Array<Double>
or
Copy code
val da: Double = a as Double
        val db: Double = b as Double
        val dc: Double = c as Double

        val sides = arrayOf<Double>(da,db,dc)
seems to compile but isn’t very succinct …
e
Copy code
arrayOf(a, b, c).sumOf { it as Double }
will sum them as doubles, but if you know it's double, you should at least have a
Triangle<Double>
d
Copy code
val sides = arrayOf<Double>(a as Double,b as Double,c as Double)
slight improvement 🤷
b
Copy code
val sides = arrayOf(a, b, c).map { it as Double }
j
What type of triangle are you getting as input? As @ephemient said, if you get a
Triangle<Double>
as input, you shouldn't need to cast. If you don't know (e.g. you get
Triangle<*>
), you shouldn't assume that you can cast to
Double
. In that case, you should use
.toDouble()
instead of
as Double
so you guarantee you're actually converting to a double in all cases
👌 1
e
none of the conversions are necessarily safe if you don't know what your inputs are.
as Double
will throw if it's any other type of `Number`;
.toDouble()
won't throw, but may lose information (
9007199254740993L.toDouble() == 9007199254740992.0
,
1.toBigDecimal().shiftLeft(1024).toDouble() == Double.POSITIVE_INFINITY
, etc.)
not to mention that
Number
is an open hierarchy so other types can be implemented, such as https://javadoc.io/doc/org.apache.commons/commons-numbers-complex/latest/index.html