【问题标题】:Migration play from 2.2 to 2.3: No implicit view available from Any从 2.2 迁移到 2.3:Any 没有可用的隐式视图
【发布时间】:2015-02-18 12:19:17
【问题描述】:

尝试将我的项目从 play 2.2.7 迁移到 2.3.8。

项目代码如下:

def setCoordinatesOfAddresses(cardId: Long, caller: Option[Tuple2[Float,Float]] = None, event: Option[Tuple2[Float,Float]] = None) {
  Logger.debug("callling SC.setCoordinatesOfAddresses")
  DB.withConnection { implicit c =>
    try {
      val query = SQL("Execute Sc.setCoordinatesOfAddresses {cardId}, {deviceLatitude}, {deviceLongitude}, NULL, NULL, {eventsLatitude}, {eventsLongitude}")
      query.on(
        "cardId" -> cardId,
        "deviceLatitude" -> caller.map(_._1).getOrElse(null),
        "deviceLongitude" -> caller.map(_._2).getOrElse(null),
        "eventsLatitude" -> event.map(_._1).getOrElse(null),
        "eventsLongitude" -> event.map(_._2).getOrElse(null) ).execute()
    } catch {
      case e: Throwable => Logger.error("error", e)
    }
  }
  Logger.debug("SC.setCoordinatesOfAddresses called")
}

编译器给了我这个错误:

Error:(384, 28) Play 2 Compiler: 
  ../app/controllers/Cards.scala:384: No implicit view available from Any => anorm.ParameterValue.
       "deviceLatitude" -> caller.map(_._1).getOrElse(null),
                     ^

我应该怎么做才能解决这个问题? 正如我从文档中了解到的,我需要定义参数类型。但我不明白在下面的代码中在哪里以及如何做到这一点。

【问题讨论】:

  • 你试过这些答案吗?
  • 我遇到了这个问题,原因是我使用的是 java 1.7 而不是最新 (2.4) 版本使用的 1.8。

标签: scala playframework playframework-2.2 playframework-2.3 anorm


【解决方案1】:

试试

val ps = Seq[anorm.ParameterValue](yourParameter1,yourParameter2) // Seq[ParameterValue]
SQL("SELECT * FROM test WHERE a={a} b={b}").
  on('a -> ps(0), 'b -> ps(1))

您正在使用Any(或其他)类型的参数,但文档说使用anorm.ParameterValue 类型

Source

【讨论】:

    【解决方案2】:

    我建议先试试val p: ParameterValue = caller

    我认为问题更多在于Tuple2[Float,Float](顺便说一句(Float, Float))没有特定的参数转换。

    在 Anorm 2.3 之前,不安全的转换使用 .toString(这会导致很多问题)。

    最好将元组转换为格式化字符串,在将其作为参数传递之前或通过添加自定义参数转换。

    (异常文档指出类型安全问题,以及如何实现转换)

    【讨论】:

      【解决方案3】:

      getOrElse(null) 引起了您的问题。这是因为您在Option[Float] 上调用getOrElse。但是 Scala 中的 null 不能分配给像 Float 这样的值类型。来自scaladoc

      Null 是所有引用类型的子类型;它的唯一实例是空引用。由于 Null 不是值类型的子类型,因此 null 不是任何此类类型的成员。 例如,不能将 null 分配给 scala.Int 类型的变量

      同样的声明适用于Float。由于nullFloat 没有共同的超类型(Any 除外),Scala 将caller.map(_._1).getOrElse(null) 推断为Any 而不是Float。这在 Play 2.2.x 中是允许的,但在 2.3.x 中,Any 不再允许作为参数传递,因为它不是类型安全的。

      解决方案?只需删除 getOrElse(null)s 就可以了。 caller.map(_._1) 是一个 Option[Float],Anorm 知道如何处理它是否为空。一般来说,在 Scala 中使用 null 是不好的做法。如果你看到自己打电话给getOrElse(null),你应该问问自己是否有更好的方法来安全地处理它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-04
        • 1970-01-01
        • 2014-08-08
        • 2020-06-18
        • 2020-05-27
        • 2017-06-19
        • 2016-12-21
        • 1970-01-01
        相关资源
        最近更新 更多