【问题标题】:Type Cast: Map[String,String] to Map[String,Object]类型转换: Map[String,String] 到 Map[String,Object]
【发布时间】:2018-03-22 11:03:18
【问题描述】:

我是 scala 的新手,当我编译我的 SBT 项目时,我看到了这个异常:

[error] C:\dev\reactive-rabbit\src\main\scala\io\scalac\amqp\impl\RabbitConnection.scala:58: type mismatch;
[error]  found   : Map[String,String] (in scala.collection.immutable)
[error]  required: Map[String,Object] (in java.util)
[error]     future(onChannel(_.exchangeBind(destination, source, routingKey, arguments)))
[error]                                                                      ^

我最近将已弃用的 JavaConversions 库替换为 JavaConverters。我的代码如下所示:

import scala.collection.JavaConvertors._
override def exchangeBind(destination: String, source: String, routingKey: String,
                        arguments: Map[String, String]) =
    future(onChannel(_.exchangeBind(destination, source, routingKey, arguments)))
      .map(_ ⇒ Exchange.BindOk())

我查看了onChannel() 的合同,它的arguments 参数需要Map[String, Object] 类型(java 集合),但我传递给它一个 Map[String, String](scala 不可变)。在将其传递给方法时如何更改此参数的数据类型?谢谢。

【问题讨论】:

    标签: java scala sbt scala-collections


    【解决方案1】:

    Scala Map 在值类型参数中是协变的,所以Map[String, String] 已经是Map[String, Object],不需要mapmapValues。您可以将其分配给具有所需类型的val 或使用类型归属:arguments: Map[String, Object]。然后拨打asJava

    (arguments: Map[String, Object]).asJava
    

    请注意,在不必要的地方使用asInstanceOf,就像其他答案一样,是不好的风格:如果您稍后更改类型,编译器无法告诉您代码需要更改的位置。

    【讨论】:

      【解决方案2】:

      使用 JavaConverters 代替 JavaConversions(已弃用)并将 String 映射到 Object 以防止出现以下错误:

      <console>:19: error: type mismatch;
       found   : java.util.Map[String,String]
       required: java.util.Map[String,Object]
      Note: String <: Object, but Java-defined trait Map is invariant in type V.
      You may wish to investigate a wildcard type such as `_ <: Object`. (SLS 3.2.10)
             javaMap = Map[String,String]().asJava
      

      .

      scala> :paste
      // Entering paste mode (ctrl-D to finish)
      
      import scala.collection.JavaConverters._
      
      var javaMap: java.util.Map[String,Object] = new java.util.HashMap()
      javaMap.put("key", "value")
      
      println(javaMap)
      
      javaMap = Map[String,String]("new_key" -> "new_value").map{case (k,v) => (k, v.asInstanceOf[Object])}.asJava
      
      // Exiting paste mode, now interpreting.
      
      {key=value}
      import scala.collection.JavaConverters._
      javaMap: java.util.Map[String,Object] = {new_key=new_value}
      javaMap: java.util.Map[String,Object] = {new_key=new_value}
      
      scala>
      

      【讨论】:

      • 使用map 的转换实际上不是必需的,只需要时间和内存。
      猜你喜欢
      • 2013-05-24
      • 2014-01-29
      • 2015-11-21
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多