【问题标题】:Convert Option[Object] to Option[Int] Implicitly将 Option[Object] 隐式转换为 Option[Int]
【发布时间】:2011-01-29 16:58:58
【问题描述】:

我正在使用返回 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 ) )

从技术上讲,它会继续,但我不断收到相同的错误:expected Int, Option[Object] found。这里是问题的重点快照:

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

我怎么做错了我的隐含?我希望它能为我完成转换,而不是我每次都必须写“asInstanceOf”。

【问题讨论】:

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

标签: scala type-conversion implicit


【解决方案1】:

您的隐式转换不适用,因为您的隐式转换会将Option[Object] 转换为Option[Int],但您的代码似乎期望它将Object 转换为Option[Int]

尝试用Some() 包装_items get( "Bar" ) 以获得Option[Object] 而不仅仅是Object,并查看您的隐式转换是否开始。

编辑:实际上,鉴于(正如您在评论中正确指出的那样),我不确定为什么这对您不起作用,Scala 映射返回选项。以下代码适用于我并打印“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 映射,那么这可以解释此处的断开连接。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-08
相关资源
最近更新 更多