【Scala】Scala ~ 基本編 / 繰り返し ~

■ はじめに

https://dk521123.hatenablog.com/entry/2023/03/12/184331

の続き。

Scala で デフォルトでは、break文がないと知ったので
ループに関して調べてみた

目次

【1】ループ
 1)while文
 2)for文
 3)foreach文
【2】使用上の注意
【3】ループの制御
 1)break
 【補足】Continue文の代替え案
【4】トラブル
 1)エラー「value foreach is not a member of java.util.List[XXXX]」発生時

【1】ループ

* 注目すべき Java との違いは、for文の構文が変わった

1)while文

* Java と変わらない

2)for文

for(i <- 1 to 3){
  println(i)
}

var array = Array(1, 2, 3)
for (x <- array) {
  println(x)
}

3)foreach文

(1 to 3).foreach( i => println(i))

var array = Array(1, 2, 3)
(array).foreach( x => println(x))

【2】使用上の注意

* 冒頭でも書いたが、

[1] break文がデフォルトではない
 => ただし、対応案あり。
 => 詳細は、後述「【3】ループの制御」の「1)break」を参照

[2] continue文もない
 => 完全にない(実装で工夫するしかない)
 => ただし、「1)break」を利用して実装可能
 => 詳細は「【補足】Continue文の代替え案」を参照

[3] Javaコードのコレクション系でのループには
 「 import scala.collection.JavaConversions._」が必要である
 => 詳細は、後述「【4】トラブル」の「1)エラー「・・・」を参照

【3】ループの制御

1)break

* scala.util.control.Breaks を利用
* Scala 2.8から使用可能

http://simplesandsamples.com/break.scala.html

サンプル

import scala.util.control.Breaks._

object  Hello {
  def main(args: Array[String]) {
    var count = 0
    breakable {
      println("Start")
      while (true) {
        count = count + 1
        println(s"count = ${count}")
        if(count == 5) {
          break
        }
      }
    }
    println(s"Done. count=${count}")
  }
}

[出力結果]

Start
count = 1
count = 2
count = 3
count = 4
count = 5
Done. count=5

【補足】Continue文の代替え案

* Scala には、Continue文はないが、前述した「1)break」を
 ループ内にすることで、Continue文と同じになる
 => 正直、いけてない、、、
 => breakableを使うことによりインデントも増えるし、可読性は下がるし、、、

https://stackoverflow.com/questions/62805222/continue-in-scala-for-loops

サンプル

import scala.util.control.Breaks._

object  Hello {
  def main(args: Array[String]) {
    println("Start")
    for(i <- 1 to 10) {
      println(s"i = ${i}")
      breakable {
        if (i % 2 != 0) {
          // break out of the 'breakable', continue the outside loop
          break
        }
        println(s"*****${i}*****")
      }
    }
    println(s"Done.")
  }
}

出力結果

Start
i = 1
i = 2
*****2*****
i = 3
i = 4
*****4*****
i = 5
i = 6
*****6*****
i = 7
i = 8
*****8*****
i = 9
i = 10
*****10*****
Done.

【4】トラブル

1)エラー「value foreach is not a member of java.util.List[XXXX]」発生時

https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java

を参考に Scala コードで書き直していたら、
以下「エラー発生コード」の★の場所で
以下「エラー内容」が表示された

エラー発生コード

// See https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
val listObjResponse = s3Client.listObjectsV2(listObjectsReqManual)

// See https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Object.html
for (content <- listObjResponse.contents()) { // ★ここでエラー★

エラー内容

value foreach is not a member of
 java.util.List[software.amazon.awssdk.services.s3.model.S3Object]

対応案

コードの冒頭に
import scala.collection.JavaConversions._
を付与する

https://github.com/sryza/aas/issues/20

関連記事

Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / Option型 ~
https://dk521123.hatenablog.com/entry/2023/03/09/000000
Scala ~ 基本編 / メソッド ~
https://dk521123.hatenablog.com/entry/2023/03/03/000000
Scala ~ 基本編 / クラス ~
https://dk521123.hatenablog.com/entry/2023/03/14/000857
Scala ~ 基本編 / コレクション ~
https://dk521123.hatenablog.com/entry/2023/03/13/000345
Scala ~ 基本編 / 日付・日時 ~
https://dk521123.hatenablog.com/entry/2023/03/08/000000
Scala ~ 基本編 / 正規表現
https://dk521123.hatenablog.com/entry/2023/03/18/034704
Scala ~ 基本編 / ジェネリック
https://dk521123.hatenablog.com/entry/2023/03/21/003817
Scala ~ ファイル名・パスの扱い ~
https://dk521123.hatenablog.com/entry/2023/03/11/000000
ScalaYAML
https://dk521123.hatenablog.com/entry/2023/03/16/012034
Spark/Scalaの開発環境構築 ~ Windows編 ~
https://dk521123.hatenablog.com/entry/2023/03/20/115450
SBT ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/22/000000