controls are essential part of any programming language. and scala is no except, being as a functional programming language, it has something that is speical from others, let's see.
// builtin_control_structurfe.scala
// this will display the list of control construct that is avaible in scala language
// 1. equational reasoning
// 1.1. if is an expression as an expression it returns value
val filename = if (!args.isEmpty) args(0) else "default.txt"
// using a val instead of a var is that it support equational erasonning , because it introduce a variable because it is equal
// equal to the expression that compute it
println( if (!args.isEmpty) args(0) else "default.txt" )
// 2. while loop (not expression)
// first of all about while loop is that there is no "continue" nor "break" in scala while, and "while-looop" in scala is a loop, not an "expression", so while
// is executed only for its side-effect, it does not return values (to be exact, it does have return value, and the return value is an Unit) ..
def gcdLoop(x : Long, y : Long) : Long = {
var a = x
var b = y
while ( a != 0) {
val temp = a
a = b % a
b = temp
}
b
}
def greet() {println("Hello")}
// def greet() = {println("Hello")}
// and there is yet another do-while in scala
// this is how you can get an empty Unit vlaue
greet() == ()
// REMEMBER: Scala assignment always results in the unit value ()
var line = ""
do {
line = readLine()
println("Read : " + line)
} while (line != "")
// a better way of replacing while in pure-funtional way is like this:
def gcd(x :long, y : Long) : Long = {
if (y == 0) x else gcd(y, x % y )
}
// 3. Functional for
// for is the functional power of scala let's see
val filesHere = (new java.io.File(".")).listFiles
val filesHere = (new java.io.File("C:\\dev\\workspace\\scala-train\\src\\controlStructures")).listFiles
// 3.1. range e.g. 1
for (i <- 1 to 4) println("Iteration " + i )
// 3.2. range e.g. 2
for (i <- 1 until 4) println("Iteration " + i )
// 3.3. filtering with if
for (file <- filesHere if file.getName.endsWith(".scala")) println("File: " + file)
// inlucde more filters as you want
for (file <- filesHere
if file.isFile
if file.getName.endsWith(".scala")
) println(file)
def fileLines (file :java.io.File) = scala.io.Source.fromFile(file).getLines().toList
// 3.4. Nested iteration
def grep(pattern : String ) =
for (file <- filesHere
if file.getName.endsWith(".scala"); // do we need the ending ';'?
line <- fileLines(file)
if line.trim.matches(pattern)
) println(file + ": " + line.trim)
grep(".*gcd.*")
// 3.5. you can do variable binding mid-stream
def grep(pattern : String ) =
for (file <- filesHere
if file.getName.endsWith(".scala"); // do we need the ending ';'?
line <- fileLines(file); // yet another needed ';'
trimmed = line.trim
if trimmed.matches(pattern)
) println(file + ": " + trimmed)
// 3.6 yield another collection
// there is another key word 'yield' for this
// for-clauses yield body
for (file <- filesHere if file.getName.endsWith(".scala")) yield file
val forLineLengths =
for {
file <- filesHere
if file.getName.endsWith(".scala")
line <- fileLines(file);
trimmed = line.trim
if trimmed.matches(".*for.*")
} yield trimmed.length
// 4. throw an exception
//
// 4.1. throw is an expression, and technically, the expression return type of 'Nothing'
val half = if (n % 2 == 0) n / 2
else throw RuntimeException("n must be even")
// 4.2. catching exception general syntax
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
try {
val f = new java.io.FileReader("input.txt")
} catch {
case ex: FileNotFoundException => Console.err.println("File not found !") // handle missing files
case ex: IOException => Console.err.println("General error reading the file !") // handle missing files
}
// 4.3. how you will use the finally clause in scala, and finally is also an expressoin, not surprise is expected from you
var f : FileReader = null
try {
// do something on the file
f = new java.io.FileReader("input.txt")
} catch {
case ex: FileNotFoundException => Console.err.println("File not found !") // handle missing files
case ex: IOException => Console.err.println("General error reading the file !") // handle missing files
} finally {
if (f != null)
f.close
}
// code below shows that the try-finally returns a value
import java.net.URL
import java.net.MalformedURLException
def urlFor(path: String) = try {
new URL(path)
} catch {
case ex: MalformedURLException => new URL("Http://www.scala-lang.org")
}
// 5. the famouse match clause in Scala
// half of the power of Scala lies in its match clause, where you can match against 1) a constant, 2. a type 3. a expression, 4. wildcards, 5. list and other collections
val firstArg = if (args.length > 0) args(0) else ""
// match clause for its side-effect
firstArg match {
case "salt" => println("pepper")
case "chips" => println("salsa")
case "eggs" => println("bacon")
case _ => println("hun?") // match a wildcards
}
// match clause is an expression
val firstArg = if (args.length > 0) args(0) else ""
val friend = firstArg match {
case "salt" => println("pepper")
case "chips" => println("salsa")
case "eggs" => println("bacon")
case _ => println("hun?") // match a wildcards
}
// 6. loop without break/continue
// 6.1 you can do that via a flag variable
var i = 0
var foundIt = false
while (i < args.length && !foundIt) {
if (!args.startsWith("-")) {
if (args(i).endsWith(".scala"))
foundIt = true
}
i = i + 1
}
// 6.2. or you can do is via the the match and recursion
def searchFrom(i : Int) : Int =
if (i >= args.length) -1
else if (args(i).startsWith("-")) searchFrom(i + 1)
else if (args(i).endsWith(".scala")) i
else searchFrom(i + 1)
val i = searchFrom(0)
// 6.3. strongly discouraged
import scala.util.control.Breaks._
import java.io._
val in = new BufferedReader (new InputStreamReader(System.in))
breakable {
while (true) {
println("? ")
if (in.readLine() == "") break
}
}
// 7. variables scope
//
val a = 1;
{
val a = 2; // compie just fine, because it shadow the the outer scope variable
println(a)
}
println(a)
// 8. a live demo
//
def makeRowSeq(row : Int) = {
for (i <- 1 to 10) yield {
val prod = i * row
val padding = " " * (4 - prod.toString().length)
padding + prod.toString()
}
}
def makeRow(row :Int) = {
makeRowSeq(row).mkString
}
def multiTable() = { // a sequence of sequence string
val tableSeq = for (i <- 1 to 10) yield {
makeRow(i)
}
tableSeq.mkString("\n")
}
println(multiTable)
本文深入探讨了Scala语言中的控制结构,包括条件表达式、循环、函数式for循环、异常处理及模式匹配等特性,并通过实例展示了Scala编程的独特之处。
3682

被折叠的 条评论
为什么被折叠?



