scala - built-in controls

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)