【问题标题】:Why does cons function called explicity works over Int in Scala?为什么称为显式的 cons 函数在 Scala 中对 Int 有效?
【发布时间】:2012-05-20 03:21:07
【问题描述】:

您可以使用以下方法在 Scala 中创建一个新列表:

1 :: 2 :: Nil

据我了解,这可以重写为:

Nil.::(2.::(1))

主要是因为:: fixty 但如果我写:

Nil :: 1 :: 2

我得到“值 :: 不是 Int 的成员”这是完全可以预期的,因为在 scaladoc Int 中没有 ::,但如果我将其翻译为:

1.::(2.::(Nil))

它可以作为输出:

List(1.0, 2.0)

看起来 scalac 自动将 12 转换为不同于 Int 的类型。那是对的吗?如果是,为什么会发生这种奇怪的类型?

【问题讨论】:

    标签: scala cons


    【解决方案1】:

    这很有趣。

    你的表情

    1.::(2.::(Nil))
    

    被编译器解析为

    1. :: (2. :: (Nil))
    

    由于:: 是右结合的,因此与

    1. :: 2. :: Nil
    

    由于1. 是编写Double 的有效方式,因此与

    1.0 :: 2.0 :: Nil
    

    这是构造List[Double]的合法表达式

    List(1.0, 2.0)
    

    【讨论】:

    • 所以这是 scala 2.9.2 的错误?或者这就是它的工作方式?
    • 这不是错误。这是完全有效的表达。省略空格时,它看起来有点滑稽。
    • 为什么“1. :: (2. :: (Nil))”被解析为“1.0 :: 2.0 :: Nil”?我虽然以 : 结尾的运算符具有向后固定性。
    • 因为在1. 中被解析为Double 1.0。换句话说,点被解释为一个数学小数点,而不是一个分隔对象与其方法的点。
    • 1. 在 2.10 中已弃用,将在 2.11 中删除。
    【解决方案2】:

    你写那个表达式

    1 :: 2 :: Nil
    

    可以改写为

    Nil.::(2.::(1))
    

    这不太正确,因为2. 被解析为Double。这可以通过在 2 左右添加括号来解决,但是编译器仍然会抱怨类 Int 不支持方法 ::

    给定的表达式可以写成

    (Nil.::(2)).::(1)
    

    你的另一个表达是

    1.::(2.::(Nil))
    

    在这里,编译器将1.2. 解析为双精度,即在读取令牌时它急切地消耗尽可能多的字符。如果你想避免这种情况,那么你可以在整数周围加上括号,或者在数字和点之间添加一个空格:

    1 .::(2 .::(Nil))
    (1).::((2).::(Nil))
    

    但是,这些表达式也会出错,因为 :: 不是 Int 类的成员(也不是任何存在隐式转换的类的成员)。

    【讨论】:

      猜你喜欢
      • 2014-07-26
      • 1970-01-01
      • 2010-11-05
      • 2010-12-01
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 2020-11-10
      相关资源
      最近更新 更多