Reputation: 7327
I am trying to use the put
method of the ContentValues
class in the Android API from Scala, but I can't figure out a way to make Scala narrow down the type of list elements. For example :
val a: List[(String, Any)](...)
val cv = new ContentValues
for ((k,v) <- a) cv.put(k,v)
...yields an error that roughly says it can't resolve the "overloaded put
method with alternatives put(String, String)
, put(String, Int),...
".
My intuition is telling me I should probably use reflection, but I can't figure out how to do it exactly. Any pointer?
Upvotes: 0
Views: 251
Reputation: 20090
This is a very famous and common problem in Scala. The type system works correctly, and developers are simply not used to it.
In strongly typed programming languages the compiler verifies rules on the types you are using and this prevents painful runtime errors. If you use reflection or casts you are allowed to force the type system and this can produce unexpected errors and problems at runtime.
Why would you want to break the rules which you largely benefit from ? A good reason is when you are designing a library and you know exactly what is going to happen in your internals (see scala collections).
When you end up using types such as Any or AnyRef you should be worried and ask yourself:
In fact I guess you are, and I propose we further investigate together why you have a List[(String,Any)]
. Let's assume you had no problems in putting data into the ContentValues
, what if later you would need to extract something from there? How would you know if it was an Int, a Double, a Float?
Upvotes: 1
Reputation: 5712
The type of your list is too imprecise. ContentValues.put
has overloads for a number of types, but they are all specific (Integer
, Float
, etc.), and no alternative for Object
.
You can:
Int
).as a last resort, do a type test:
for ((k, v) <- a) v match {
case n: Int => cv.put(k, v)
case d: Double => cv.put(k, d)
//...
}
Upvotes: 1