Frage

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?

War es hilfreich?

Lösung

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:

  • make the list type more precise, in case the list has only elements of one type (say, Int).
  • use an HList, but beware of type wizardry. It may be overkill in this case
  • 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)
      //...
    }
    

Andere Tipps

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:

  • why I am going so up in the hierarchy ?
  • Am I probably using an anti pattern or a bad constructor for a strongly typed programming language?

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?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top