Skip to content

Scala 循环语句

Scala 提供了多种循环结构,包括 for 循环、while 循环等。Scala 的循环具有函数式编程的特色,支持生成器、过滤器和推导式。

for 循环

基本 for 循环

scala
object BasicForLoop {
  def main(args: Array[String]): Unit = {
    // 基本范围循环
    println("基本 for 循环:")
    for (i <- 1 to 5) {
      println(s"i = $i")
    }
    
    println("\nuntil 循环 (不包含结束值):")
    for (i <- 1 until 5) {
      println(s"i = $i")
    }
    
    println("\n步长循环:")
    for (i <- 1 to 10 by 2) {
      println(s"i = $i")
    }
    
    println("\n倒序循环:")
    for (i <- 10 to 1 by -1) {
      println(s"i = $i")
    }
  }
}

遍历集合

scala
object CollectionIteration {
  def main(args: Array[String]): Unit = {
    val fruits = List("苹果", "香蕉", "橙子", "葡萄")
    val numbers = Array(1, 2, 3, 4, 5)
    
    println("遍历列表:")
    for (fruit <- fruits) {
      println(s"水果: $fruit")
    }
    
    println("\n遍历数组:")
    for (num <- numbers) {
      println(s"数字: $num")
    }
    
    println("\n带索引遍历:")
    for ((fruit, index) <- fruits.zipWithIndex) {
      println(s"第${index + 1}个水果: $fruit")
    }
    
    println("\n使用 indices:")
    for (i <- fruits.indices) {
      println(s"索引 $i: ${fruits(i)}")
    }
  }
}

嵌套 for 循环

scala
object NestedForLoop {
  def main(args: Array[String]): Unit = {
    println("嵌套 for 循环 - 乘法表:")
    for (i <- 1 to 3) {
      for (j <- 1 to 3) {
        print(s"${i * j}\t")
      }
      println()
    }
    
    println("\n使用分号的嵌套循环:")
    for (i <- 1 to 3; j <- 1 to 3) {
      println(s"($i, $j) = ${i * j}")
    }
    
    println("\n三层嵌套:")
    for {
      x <- 1 to 2
      y <- 1 to 2
      z <- 1 to 2
    } {
      println(s"($x, $y, $z)")
    }
  }
}

带条件的 for 循环

scala
object ConditionalForLoop {
  def main(args: Array[String]): Unit = {
    val numbers = 1 to 20
    
    println("偶数:")
    for (num <- numbers if num % 2 == 0) {
      println(num)
    }
    
    println("\n能被3整除的数:")
    for (num <- numbers if num % 3 == 0) {
      println(num)
    }
    
    println("\n多个条件:")
    for {
      num <- numbers
      if num % 2 == 0
      if num > 10
    } {
      println(s"大于10的偶数: $num")
    }
    
    println("\n字符串过滤:")
    val words = List("hello", "world", "scala", "programming", "fun")
    for (word <- words if word.length > 4) {
      println(s"长单词: $word")
    }
  }
}

for 推导式 (for comprehension)

scala
object ForComprehension {
  def main(args: Array[String]): Unit = {
    val numbers = 1 to 10
    
    // 生成新的集合
    val squares = for (num <- numbers) yield num * num
    println(s"平方数: $squares")
    
    val evenSquares = for {
      num <- numbers
      if num % 2 == 0
    } yield num * num
    println(s"偶数的平方: $evenSquares")
    
    // 字符串处理
    val words = List("hello", "world", "scala")
    val upperWords = for (word <- words) yield word.toUpperCase
    println(s"大写单词: $upperWords")
    
    // 复杂的推导式
    val coordinates = for {
      x <- 1 to 3
      y <- 1 to 3
      if x != y
    } yield (x, y)
    println(s"坐标对 (x != y): $coordinates")
    
    // 嵌套集合处理
    val matrix = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
    val flattenedDoubled = for {
      row <- matrix
      element <- row
    } yield element * 2
    println(s"扁平化并翻倍: $flattenedDoubled")
  }
}

while 循环

基本 while 循环

scala
object BasicWhileLoop {
  def main(args: Array[String]): Unit = {
    var i = 1
    
    println("while 循环:")
    while (i <= 5) {
      println(s"i = $i")
      i += 1
    }
    
    // 计算阶乘
    var n = 5
    var factorial = 1
    var counter = 1
    
    while (counter <= n) {
      factorial *= counter
      counter += 1
    }
    println(s"$n! = $factorial")
  }
}

do-while 循环

scala
object DoWhileLoop {
  def main(args: Array[String]): Unit = {
    var i = 1
    
    println("do-while 循环:")
    do {
      println(s"i = $i")
      i += 1
    } while (i <= 5)
    
    // 至少执行一次的示例
    var input = 0
    do {
      println("请输入一个正数:")
      input = scala.io.StdIn.readInt()
      if (input <= 0) {
        println("输入无效,请重新输入!")
      }
    } while (input <= 0)
    
    println(s"您输入的正数是: $input")
  }
}

循环控制

break 和 continue (使用 Breaks)

scala
import scala.util.control.Breaks._

object LoopControl {
  def main(args: Array[String]): Unit = {
    println("使用 break:")
    breakable {
      for (i <- 1 to 10) {
        if (i == 6) break()
        println(s"i = $i")
      }
    }
    
    println("\n使用 continue (跳过偶数):")
    for (i <- 1 to 10) {
      breakable {
        if (i % 2 == 0) break()  // 相当于 continue
        println(s"奇数: $i")
      }
    }
    
    println("\n嵌套循环中的 break:")
    breakable {
      for (i <- 1 to 5) {
        for (j <- 1 to 5) {
          if (i * j > 10) break()
          println(s"$i * $j = ${i * j}")
        }
      }
    }
  }
}

标签化的 break

scala
import scala.util.control.Breaks._

object LabeledBreak {
  def main(args: Array[String]): Unit = {
    println("标签化的 break:")
    
    outer: breakable {
      for (i <- 1 to 5) {
        inner: breakable {
          for (j <- 1 to 5) {
            if (i == 3 && j == 3) {
              println(s"在 ($i, $j) 处跳出外层循环")
              break(outer)
            }
            println(s"($i, $j)")
          }
        }
      }
    }
    
    println("外层循环结束")
  }
}

函数式循环替代方案

使用高阶函数

scala
object FunctionalLoops {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3, 4, 5)
    
    println("使用 foreach:")
    numbers.foreach(num => println(s"数字: $num"))
    
    println("\n使用 map:")
    val doubled = numbers.map(_ * 2)
    println(s"翻倍: $doubled")
    
    println("\n使用 filter:")
    val evens = numbers.filter(_ % 2 == 0)
    println(s"偶数: $evens")
    
    println("\n使用 reduce:")
    val sum = numbers.reduce(_ + _)
    println(s"总和: $sum")
    
    println("\n使用 fold:")
    val product = numbers.fold(1)(_ * _)
    println(s"乘积: $product")
    
    println("\n使用 zipWithIndex:")
    numbers.zipWithIndex.foreach { case (value, index) =>
      println(s"索引 $index: $value")
    }
  }
}

递归替代循环

scala
object RecursiveLoops {
  // 递归计算阶乘
  def factorial(n: Int): Int = {
    if (n <= 1) 1
    else n * factorial(n - 1)
  }
  
  // 尾递归计算阶乘
  def factorialTailRec(n: Int): Int = {
    @annotation.tailrec
    def loop(n: Int, acc: Int): Int = {
      if (n <= 1) acc
      else loop(n - 1, n * acc)
    }
    loop(n, 1)
  }
  
  // 递归遍历列表
  def printList[T](list: List[T]): Unit = list match {
    case Nil => println("列表结束")
    case head :: tail =>
      println(s"元素: $head")
      printList(tail)
  }
  
  // 递归计算斐波那契数列
  def fibonacci(n: Int): Int = {
    if (n <= 1) n
    else fibonacci(n - 1) + fibonacci(n - 2)
  }
  
  // 尾递归斐波那契
  def fibonacciTailRec(n: Int): Int = {
    @annotation.tailrec
    def loop(n: Int, prev: Int, curr: Int): Int = {
      if (n == 0) prev
      else loop(n - 1, curr, prev + curr)
    }
    loop(n, 0, 1)
  }
  
  def main(args: Array[String]): Unit = {
    println(s"5! = ${factorial(5)}")
    println(s"5! (尾递归) = ${factorialTailRec(5)}")
    
    val list = List(1, 2, 3, 4, 5)
    printList(list)
    
    println(s"斐波那契数列第10项: ${fibonacci(10)}")
    println(s"斐波那契数列第10项 (尾递归): ${fibonacciTailRec(10)}")
  }
}

实践示例

数字猜测游戏

scala
import scala.util.Random
import scala.io.StdIn

object NumberGuessingGame {
  def main(args: Array[String]): Unit = {
    val random = new Random()
    val targetNumber = random.nextInt(100) + 1
    var attempts = 0
    var guessed = false
    
    println("欢迎来到数字猜测游戏!")
    println("我想了一个1到100之间的数字,请猜猜是多少?")
    
    while (!guessed && attempts < 10) {
      print("请输入您的猜测: ")
      val guess = StdIn.readInt()
      attempts += 1
      
      if (guess == targetNumber) {
        println(s"恭喜!您在第 $attempts 次尝试中猜对了!")
        guessed = true
      } else if (guess < targetNumber) {
        println("太小了!")
      } else {
        println("太大了!")
      }
      
      if (!guessed && attempts < 10) {
        println(s"您还有 ${10 - attempts} 次机会")
      }
    }
    
    if (!guessed) {
      println(s"游戏结束!正确答案是 $targetNumber")
    }
  }
}

矩阵操作

scala
object MatrixOperations {
  def printMatrix(matrix: Array[Array[Int]]): Unit = {
    for (row <- matrix) {
      for (element <- row) {
        print(s"$element\t")
      }
      println()
    }
  }
  
  def createMatrix(rows: Int, cols: Int): Array[Array[Int]] = {
    val matrix = Array.ofDim[Int](rows, cols)
    var counter = 1
    
    for (i <- matrix.indices) {
      for (j <- matrix(i).indices) {
        matrix(i)(j) = counter
        counter += 1
      }
    }
    matrix
  }
  
  def transposeMatrix(matrix: Array[Array[Int]]): Array[Array[Int]] = {
    val rows = matrix.length
    val cols = matrix(0).length
    val transposed = Array.ofDim[Int](cols, rows)
    
    for (i <- matrix.indices) {
      for (j <- matrix(i).indices) {
        transposed(j)(i) = matrix(i)(j)
      }
    }
    transposed
  }
  
  def main(args: Array[String]): Unit = {
    println("创建 3x4 矩阵:")
    val matrix = createMatrix(3, 4)
    printMatrix(matrix)
    
    println("\n转置矩阵:")
    val transposed = transposeMatrix(matrix)
    printMatrix(transposed)
  }
}

素数生成器

scala
object PrimeGenerator {
  def isPrime(n: Int): Boolean = {
    if (n < 2) return false
    if (n == 2) return true
    if (n % 2 == 0) return false
    
    var i = 3
    while (i * i <= n) {
      if (n % i == 0) return false
      i += 2
    }
    true
  }
  
  def generatePrimes(limit: Int): List[Int] = {
    val primes = for {
      num <- 2 to limit
      if isPrime(num)
    } yield num
    
    primes.toList
  }
  
  def sieveOfEratosthenes(limit: Int): List[Int] = {
    val isPrime = Array.fill(limit + 1)(true)
    isPrime(0) = false
    if (limit >= 1) isPrime(1) = false
    
    for (i <- 2 to math.sqrt(limit).toInt) {
      if (isPrime(i)) {
        for (j <- i * i to limit by i) {
          isPrime(j) = false
        }
      }
    }
    
    (for (i <- isPrime.indices if isPrime(i)) yield i).toList
  }
  
  def main(args: Array[String]): Unit = {
    val limit = 50
    
    println(s"使用试除法生成 $limit 以内的素数:")
    val primes1 = generatePrimes(limit)
    println(primes1.mkString(", "))
    
    println(s"\n使用埃拉托斯特尼筛法生成 $limit 以内的素数:")
    val primes2 = sieveOfEratosthenes(limit)
    println(primes2.mkString(", "))
  }
}

性能考虑

  1. for 推导式 vs 命令式循环:for 推导式更函数式,但可能有性能开销
  2. 尾递归优化:使用 @tailrec 注解确保尾递归优化
  3. 避免嵌套循环:考虑使用函数式方法如 flatMap
  4. 使用 View:对于大集合,使用 view 进行惰性求值
scala
object PerformanceConsiderations {
  def main(args: Array[String]): Unit = {
    val largeRange = 1 to 1000000
    
    // 使用 view 进行惰性求值
    val result = largeRange.view
      .filter(_ % 2 == 0)
      .map(_ * 2)
      .take(10)
      .toList
    
    println(s"前10个偶数翻倍: $result")
  }
}

掌握循环结构对于编写高效的 Scala 程序至关重要,同时要学会在适当的时候使用函数式编程的替代方案。

本站内容仅供学习和研究使用。