0

我正在尝试使用来自 Scala 的 Android APIput中的类的方法ContentValues,但我想不出一种方法来使 Scala 缩小列表元素的类型。例如 :

val a: List[(String, Any)](...)
val cv = new ContentValues
for ((k,v) <- a) cv.put(k,v)

...产生一个错误,粗略地说它无法解决“具有替代方案的重载put方法”put(String, String)put(String, Int),...

我的直觉告诉我我可能应该使用反射,但我无法弄清楚如何准确地做到这一点。任何指针?

4

2 回答 2

1

您的列表类型太不精确。ContentValues.put有许多类型的重载,但它们都是特定的(IntegerFloat等),并且没有替代Object.

你可以:

  • 使列表类型更精确,以防列表只有一种类型的元素(例如,Int)。
  • 使用HList,但要注意类型巫术。在这种情况下可能有点矫枉过正
  • 作为最后的手段,做一个类型测试:

    for ((k, v) <- a) v match {
      case n: Int => cv.put(k, v)
      case d: Double => cv.put(k, d)
      //...
    }
    
于 2013-04-03T08:38:25.993 回答
1

这是 Scala 中一个非常著名且常见的问题。类型系统工作正常,开发人员根本不习惯。

在强类型编程语言中,编译器会验证您正在使用的类型的规则,这可以防止痛苦的运行时错误。如果您使用反射或强制转换,您可以强制使用类型系统,这会在运行时产生意外错误和问题。

你为什么要打破你主要受益的规则?一个很好的理由是当你设计一个库并且你确切地知道你的内部会发生什么(参见 scala 集合)。

当您最终使用 Any 或 AnyRef 等类型时,您应该担心并问自己:

  • 为什么我会在等级制度中如此上升?
  • 我是否可能对强类型编程语言使用了反模式或错误的构造函数?

事实上我猜你是,我建议我们一起进一步调查为什么你有一个List[(String,Any)]. 假设您在将数据放入 中没有问题ContentValues,如果稍后您需要从那里提取一些东西怎么办?你怎么知道它是 Int、Double 还是 Float?

于 2013-04-03T08:51:58.750 回答