【问题标题】:Understand Scala immutable Map behaviour理解 Scala 不可变的 Map 行为
【发布时间】:2018-02-20 11:15:29
【问题描述】:

我使用了一个 scala 不可变映射,如下所示。

val d = "4.55"

  1. 这工作正常。

    val  properties = Map("title"->"title" , "value" -> d )
    
  2. 它从 [String , AnyRef] 转换为 [String, Any]

    val  properties = Map("title"->"title" , "value" -> d.toDouble )
    
  3. 无法从 Double 转换为 Object ,运行时错误

    val  properties:Map[String,Object] = Map("title"->"title" , "value" -> d.toDouble )
    

    为什么对象不能接受 Double?

  4. 工作正常。

    val  properties:Map[String,Object] = Map("title"->"title" , "value" -> d.toDouble.asInstanceOf[Object] )
    

无法理解 Immutable Map 行为的四种场景。

【问题讨论】:

  • 我是一名 Java 开发人员,只是路过,但我猜对了(因为 Scala 在 JVM 上运行,也许它可以提供帮助)。在 Java 中,泛型存在类型擦除,因此类型信息仅在编译时出现。我不认为这是全部情况,但可能与这种行为有关。
  • val properties[String, Object] = ... 不是有效的 Scala 语法
  • 是的,我已经编辑了语法,我忘记了冒号
  • "为什么对象不能接受 java.lang.Double?"可以,但 toDouble 返回 Double 而不是 java.lang.Double
  • @SagarVaghela 带冒号也无效。

标签: scala immutability autoboxing


【解决方案1】:

最重要的是:Scala 没有 Java 的原始类型。

Scala的Double是一个类,继承自AnyVal,有自己的方法

但是Java的Object是所有引用类型的基类,又名...Class

所以,您在这里所做的是使用 Object 作为 Double 的基类。

在我看来,
Scala 的 AnyRef 是对应于 Java 的 Object 的类型。
Scala 的 AnyVal 对应于 Java 的 Primitive Types

【讨论】:

    【解决方案2】:

    正如您从 Scala 类层次结构中看到的...

    ...java.lang.Object 的 Scala 等价物是 AnyRef,类型 String 是该家族的一部分,但 Scala Double 属于 AnyVal。当编译器必须协调这两种类型时,它会找到类型 Any,如果没有强制(即强制转换),则无法将其提升为类型 AnyRef/Object

    如果您使用d.toSeq 而不是d.toDouble,编译器会立即转到AnyRef/Object

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-11
      • 2018-07-01
      • 2013-06-03
      • 1970-01-01
      • 2017-12-15
      • 1970-01-01
      • 2017-05-20
      相关资源
      最近更新 更多