【问题标题】:spark-shell cannot parse Scala lines that start with dot / periodspark-shell 无法解析以点/句点开头的 Scala 行
【发布时间】:2016-04-12 20:03:32
【问题描述】:

每当我在网上找到一些 Scala / Spark 代码时,我都想直接将其粘贴到 spark-shell 中尝试一下。 (我在 CentOS 和 Mac OS 上都使用带有 Spark 1.6 的 spark-shell。)

一般来说,这种方法效果很好,但是当行以点/句点开头(表示持续的方法调用)时,我总是遇到问题。如果我将点移到上一行,它会起作用。

示例:这是我在网上找到的一些代码:

val paramMap = ParamMap(lr.maxIter -> 20)
  .put(lr.maxIter, 30) 
  .put(lr.regParam -> 0.1, lr.threshold -> 0.55)

所以当我将它直接粘贴到 spark-shell 中时,我看到了这个错误:

scala> val paramMap = ParamMap(lr.maxIter -> 20)
paramMap: org.apache.spark.ml.param.ParamMap = 
{
    logreg_d63b85553548-maxIter: 20
}

scala>   .put(lr.maxIter, 30) 
<console>:1: error: illegal start of definition
         .put(lr.maxIter, 30) 
         ^

scala>   .put(lr.regParam -> 0.1, lr.threshold -> 0.55)
<console>:1: error: illegal start of definition
         .put(lr.regParam -> 0.1, lr.threshold -> 0.55)
         ^

但是,当我将点移到上一行时,一切正常。

scala> val paramMap = ParamMap(lr.maxIter -> 20).
     | put(lr.maxIter, 30).
     | put(lr.regParam -> 0.1, lr.threshold -> 0.55)
paramMap: org.apache.spark.ml.param.ParamMap = 
{
    logreg_d63b85553548-maxIter: 30,
    logreg_d63b85553548-regParam: 0.1,
    logreg_d63b85553548-threshold: 0.55
}

有没有办法配置 spark-shell 以便它接受以点开头的行(或等效地,即使它们不以点结尾,它也会继续行)?

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    不能有前导空格。

    scala> "3"
    res0: String = 3
    
    scala> .toInt
    res1: Int = 3
    
    scala> "3"
    res2: String = 3
    
    scala>   .toInt
    <console>:1: error: illegal start of definition
      .toInt
      ^
    

    PS:也许它应该在检测到点时忽略空格。针对该问题添加了一个 JIRA here

    【讨论】:

    • ps) 也许在检测点选择时它应该忽略前导空格。
    【解决方案2】:

    使用:paste 命令:

    scala> :paste
    // Entering paste mode (ctrl-D to finish)
    
    if (true)
      print("that was true")
    else
      print("false")
    
    // Exiting paste mode, now interpreting.
    
    that was true
    

    【讨论】:

    • 当你想粘贴代码时,输​​入“:paste”真的很不方便。
    【解决方案3】:

    你也可以用花括号括起来你的表达式

    val paramMap = { ParamMap(lr.maxIter -> 20)
      .put(lr.maxIter, 30) 
      .put(lr.regParam -> 0.1, lr.threshold -> 0.55)
    }
    

    这是因为:REPL 是“贪婪的”,会消耗您输入的第一个完整语句,因此尝试将代码块粘贴到其中可能会失败

    更多详情请见:http://alvinalexander.com/scala/scala-repl-how-to-paste-load-blocks-of-source-code

    还有一个不错的功能:paste -raw

    http://docs.scala-lang.org/overviews/repl/overview.html

    【讨论】:

      【解决方案4】:

      Spark shell 有一个内置机制,允许粘贴多行 Spark Scala 代码或逐行编写 Spark Scala 代码:通过将代码包装在括号 () 中。不需要将点移动到行尾。

      在您的示例中以val paramMap = ( 开头。从这里您可以手动编写每一行或粘贴到您的多行线性回归超参数代码中。然后在你的代码完成后再加一个括号) 来封装它。使用此方法时,不要使用制表符进行缩进,而是使用两个空格。

      完整代码示例:

      scala> val paramMap = (ParamMap(lr.maxIter -> 20)
       |   .put(lr.maxIter, 30)
       |   .put(lr.regParam -> 0.1, lr.threshold -> 0.55)
       | )
      

      【讨论】:

        【解决方案5】:

        你也可以把句号放在前面,这样就可以了。虽然这可能会打破风格约定

        val paramMap = ParamMap(lr.maxIter -> 20).
          put(lr.maxIter, 30).
          put(lr.regParam -> 0.1, lr.threshold -> 0.55)
        

        【讨论】:

          猜你喜欢
          • 2021-03-16
          • 2016-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多