【问题标题】:Why do I get different results when using a List than using a Tuple?为什么使用 List 时得到的结果与使用 Tuple 不同?
【发布时间】:2020-05-23 03:44:58
【问题描述】:

如果我尝试:

val someInput = List(('a', 2), ('b', 2))

for {
  (k,v) <- someInput
} yield (k,v)


 res0: List[(Char, Int)] = List((a,2), (b,2))

如果我这样做了:

for {
  (k,v) <- someInput
} yield List(k,v)

res0: List[List[Int]] = List(List(97, 2), List(98, 2))

我不明白为什么在使用列表时会得到 97 和 98?

【问题讨论】:

    标签: scala


    【解决方案1】:

    编译器会自动将 Char 的键转换为 Int(因为 JVM 字符表示 Unicode 代码点),因为值是 Int 并且列表是同质的。 97 和 98 只是 'a''b' 在 Unicode(和 ASCII)中的十进制表示。

    请参阅this question,了解为什么 Char 被隐式转换为 Int(请注意,Int 未转换为 Char,因为它是 32 位,而 Char 只有 16 位,所以它可能是有损转换)。

    你也可以这样做

    for {
      (k,v) <- someInput
    } yield List((k,v))
    

    这样您就可以生成(Char, Int) 的单例列表,并且您的类型会被保留。结果将是List(List((a, 2)), List((b, 2)))

    【讨论】:

      【解决方案2】:

      Scala 2 在推断原始数字类型的最小上限时使用weak conformance 关系,使得

      List('a', 2)
      

      输入到List[Int],而不是可能预期的List[AnyVal]。编译器插入toInt

      List('a'.toInt, 2)
      

      正如SLS 6.26.1 Value Conversions所解释的那样

      如果?有一个原始数字类型weakly conforms 预期类型,它使用以下之一扩展为预期类型 数值转换方法toShorttoChartoInttoLongtoFloattoDouble 在标准库中定义。

      例如,弱一致性似乎是 Scala 3 中的 dropped feature

      Starting dotty REPL...
      scala> val a = 'a'
           | val i = 2
      val a: Char = a
      val i: Int = 2
      
      scala> List(a, i)
      val res0: List[AnyVal] = List(a, 2)
      

      我们看到 dotty 推断出List[AnyVal]。如果我们尝试强制类型为List[Int],则会引发警告

      scala> val l: List[Int] = List(a,i)
      1 |val l: List[Int] = List(a,i)
        |                        ^
        |Use of implicit conversion method char2int in object Char should be enabled
        |by adding the import clause 'import scala.language.implicitConversions'
        |or by setting the compiler option -language:implicitConversions.
        |See the Scala docs for value scala.language.implicitConversions for a discussion
        |why the feature should be explicitly enabled.
      val l: List[Int] = List(97, 2)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-06
        • 2014-11-23
        • 2020-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多