Scala 隐式地将选项[Object]转换为选项[Int]

Scala 隐式地将选项[Object]转换为选项[Int],scala,type-conversion,implicit,Scala,Type Conversion,Implicit,我正在使用返回Java.lang.object的遗留Java代码。我将它传递到一个函数中,我想做一些隐式转换,例如: implicit def asInt( _in:Option[Object] ) = _in asInstanceOf[ Option[Int] ] implicit def asDouble( _in:Option[Object] = _in asInstanceOf[ Option[Double] ] private def parseEntry( _name:String

我正在使用返回Java.lang.object的遗留Java代码。我将它传递到一个函数中,我想做一些隐式转换,例如:

implicit def asInt( _in:Option[Object] ) = _in asInstanceOf[ Option[Int] ]
implicit def asDouble( _in:Option[Object] = _in asInstanceOf[ Option[Double] ]

private def parseEntry( _name:String, _items:Map[String,Object] ) = _name match{
    case docName.m_Constants =>
        new Constants( _items get( Constants m_Epsilon ), _items get( Constant m_Rho ),
                       _items get( Constants m_N ) )
从技术上讲,它还在继续,但我一直得到相同的错误:预期Int,Option[Object]found。下面是问题的重点快照:

private def foo( _items:Map[String,Object] ) ={
    val bar:Option[Int] = _items get( "Bar" ) }

我是怎么做的,这是错的?我希望它能为我进行转换,而不是每次都要编写“asInstanceOf”。

您的隐式转换不适用,因为您的隐式转换将
选项[Object]
转换为
选项[Int]
,但您的代码似乎希望它将
对象
转换为
选项[Int]

尝试使用
Some()
包装
\u items get(“Bar”)
,以获取
选项[Object]
,而不仅仅是
对象,然后查看隐式转换是否生效

编辑:事实上,我不确定为什么这对您不起作用,因为(正如您在评论中正确指出的那样),Scala maps返回选项。以下代码适用于我并按我的预期打印“37”:

import scala.collection.mutable.Map
import scala.collection.mutable.HashMap

object ImplicitConversions {
    implicit def asInt( _in:Option[Object] ) = _in.asInstanceOf[Option[Int]]
    implicit def asDouble( _in:Option[Object] ) = _in.asInstanceOf[Option[Double]]

    private def foo( _items:Map[String,Object] ) = {
        val bar:Option[Int] = _items.get("Bar")
        println(bar.get.intValue)
    }

    def main(args: Array[String]) {
      val map:Map[String,Object] = new HashMap[String, Object]
      map.put("Bar", Integer.valueOf(37))
      foo(map)
    }
}
但是,如果我使用Java映射,那么使用
Some()
包装可以:

import java.util.Map
import java.util.HashMap

object ImplicitConversions {
    implicit def asInt( _in:Option[Object] ) = _in.asInstanceOf[Option[Int]]
    implicit def asDouble( _in:Option[Object] ) = _in.asInstanceOf[Option[Double]]

    private def foo( _items:Map[String,Object] ) = {
        val intermediate = Some(_items.get("Bar"))
        val bar:Option[Int] = intermediate
        println(bar.get.intValue)
    }

    def main(args: Array[String]) {
      val map:Map[String,Object] = new HashMap[String, Object]
      map.put("Bar", Integer.valueOf(37))
      foo(map)
    }
}
(请注意,我确实必须将
Some()
的结果存储在一个中间变量中,才能使转换生效-也许Scala方面的专家可以告诉我如何避免中间步骤;-)


Scala和Java映射是否可能在您的代码中混为一谈?您确实说过要调用遗留Java代码,这就是为什么您必须首先进行所有隐式转换的原因。如果您认为使用的是Scala映射,而使用的是Java映射,那么这就可以解释这里的断开。

但是get-from-Map返回一个选项[B],顺便说一句,我真的不建议像这样的隐式转换。任何时候你必须在隐式转换中进行转换,你都应该将其视为一种迹象,表明你可能偏离了推荐的路径。那么,在处理java.lang.object时,你会推荐什么呢?尽管我回答了这个问题(嘿,我喜欢有一个我可以回答的问题:-),我同意@Daniel的观点,像这样的隐式类型转换应该小心使用。当然,在某些情况下,运行时类型检查和强制转换是不可避免的,例如在处理返回缺少泛型类型信息的集合的遗留Java代码时。尽管如此,通过使这些强制转换隐式化,您节省了一些输入(耶!),但使代码的未来用户更难看到运行时类强制转换异常(boo!)的风险。