0

私は Scala を初めて使用し、機能的な方法で使用しようとしています。ここに私の質問があります:

  1. 「<-」演算子を使用して、関数の戻り値を持つ「cnt」変数の新しいバインディングを作成できないのはなぜですか?

  2. 機能的な方法で不変変数をインクリメントするにはどうすればよいですか (Haskell <-) に似ていますか? 実験のために、可変変数を使用したくありません。

    import scala.io.Source
    object MyProgram {
    
      def main(args: Array[String]): Unit = {
        if (args.length > 0) {
          val lines = Source.fromFile(args(0)).getLines()
          val cnt = 0
          for (line <- lines) {
            cnt <- readLines(line, cnt)
          }
          Console.err.println("cnt = "+cnt)
        }
      }
    
      def readLines(line: String, cnt:Int):Int = {
        println(line.length + " " + line)
        val newCnt = cnt + 1
        return (newCnt)
      }
    }   
    

副作用に関しては、 (line <- lines) がこれほど破壊的であるとは予想できませんでした! 行イテレータを完全に巻き戻します。したがって、次のスニペットを実行すると size = 0 になります。

val lines = Source.fromFile(args(0)).getLines()
var cnt = 0
for (line <- lines) {
  cnt = readLines(line, cnt)
}
val size = lines.size

このようなよく隠された副作用を持つことは、通常の Scala の慣行ですか?

4

3 に答える 3

2

あなたはそのように折りたたむことができますlines

val lines = Source.fromFile(args(0)).getLines()
val cnt = lines.foldLeft(0) { case (count, line) => readLines(line, count) }
Console.err.println("cnt = "+cnt)

あなたのreadLinesメソッドはへの呼び出しで副作用を起こしますがprintln、使用foldLeftするとリストの左から右への処理が保証されるため、出力は同じである必要があります。

于 2013-03-19T14:04:07.887 に答える
1

'<-'演算子を使用して、関数の戻り値で不変の'cnt'変数を再割り当てできないのはなぜですか?

なんで?:Javaの経験がある場合、<-は。と同様の意味を持ちfor(Item x: someCollection)ます。これは、コレクションから現在のアイテムを取得して名前を付けるための単なる構文糖衣であり、一般にバインド演算子ではありません。

さらに、不変の 撞着語を再割り当てしませんか?

不変変数を関数型でインクリメントするにはどうすればよいですか(Haskell <-と同様)?

Scalaの人々は通常使用します.zipWithIndexが、これは理解のために内部のカウンターを使用する場合にのみ機能します。

for((x, i) <- lines.zipWithIndex) { println("the counter value is" + i) } 

lines.countですから、fold / reduceを使い続けるか、使用するか、iable=に新しい値を割り当てる必要があると思いますvar

于 2013-03-19T14:03:25.177 に答える
0

<-は演算子ではなく、式に使用される構文にすぎません。を使用する必要があります=。使用する場合<-は、for-iteration-expression内にある必要があります。また、をインクリメントすることはできませんval。その変数を変更する場合は、それを。にしvarます。

于 2013-03-19T14:03:31.370 に答える