一塊兒學scala--控制結構和函數

條件表達式

與java/c++不一樣的是,scala中 if / else語法是有返回值的,這個值就是跟在if / else 以後的最後一個表達式的值。java

val s:String = if(1 > 0) "yes" else "no" 
// 返回值是if/else表達式返回值的公共超類型,這裏是String。
val value: Any = if (1 > 0) "yes" else 1
// 若是else沒有返回值,默認就爲Unit類型,至關於java中的void,用()表示。
val value: Any = if (1 > 0) "yes" else ()

塊表達式和賦值

在scala中,塊表達式也是有值的,這個值就是塊中的最後一個表達式的值。賦值語句的值爲Unit類型。c++

val distance: Double = {
  val a = 2
  val b = 4
  scala.math.sqrt(a * a + b * b)
}

輸入輸出

在scala.io.StdIn類下包含輸入的各類方法。數組

val in: StdIn.type = scala.io.StdIn
val n: Int = in.readInt()
val bool: Boolean = in.readBoolean()
val d: Double = in.readDouble()
val str: String = in.readLine()
//格式化輸入
val in: StdIn.type = scala.io.StdIn
val list: List[Any] = in.readf("this is {0,number,integer}")
// 輸入this is 1.22 輸出 1

若是要打印一個值,咱們用print或println函數,後者會追加一個換行符。
scala中的字符串插值有三種。安全

  • f:帶格式化命令,相似其餘語言的printf函數。
  • s:不帶格式化命令,經常使用
  • raw:轉義序列不會被求值。
val name = "yoleen"
val age = 10
print(s"My name is $name and I am ${age*2} years old\n")
//My name is yoleen and I am 20 years old
print(f"My name is $name%s and I am ${age*2.5}%.2f years old\n")
//My name is yoleen and I am 25.00 years old
print(raw"My name is $name and I am ${age*2.5} years old\n")
//My name is yoleen and I am 25.0 years old\n

循環

scala有與java和c++相同的while和do循環。例如:函數

while(n>0){
  r *= n
  n-=1 //沒有-- 和 ++ 操做符
}

在scala中for循環是這樣的:this

// for 的語法結構
for(elem <- 表達式){
//elem爲何值取決於表達式裏面的值。
}

for(i <- 1 to 10){
// RichInt類中的to方法,返回1 to n(包含n)的Range區間
	n += i
}

for(elem <- "hello"){
//elem = 'h'...'o'
}

//接Boolean表達式
for(i <- 1 to 10 if(i%2==0)){
	print(f"$i%3d")
}//將交出2  4  6  8 10

//多重循環 九九乘法表
for(i <- 1 to 9; j <- 1 to i){
   print(s"$i*$j=${i*j} ")
   if(i==j){
     println //沒參省略括號
   }
 }

//for推導式,使用yield生成一個長度不可變的數組
//注意for後面沒有{}
val ints: immutable.IndexedSeq[Int] = for (i <- 1 to 9; j <- 1 to i) yield {
   i*j
}

函數

要定義函數,你須要給出函數的名稱、參數和函數體,例如:線程

def main(args: Array[String])= {}

你必需要給出全部參數的類型,不過,只要不是遞歸函數,你能夠不指定函數的返回類型。scala編譯器能經過返回值推斷出返回類型。
對於遞歸函數咱們必需要指定返回類型,例如:scala

// 遞歸求字符串中的全部字符的乘積。
def recursive(s:String,i:Int):Long={
  if(i<s.length){
    recursive(s,i+1)*s(i).toInt
  }else{
    1
  }
}

默認參數和帶名參數

在函數定義時能夠帶上初始值。如:3d

def sayHello(name:String,s:String="hello,",left:String="[",right:String="]")={
   s+left+name+right
}//輸入name="yoleen" 將輸出 hello,[yoleen]

對於參數較多的函數,帶名參數能顯得程序更加易讀。
注意參數並不須要跟參數列表順序一致。code

sayHello(s="Hi,",name="yoleen",right="]!")
//將輸出 Hi,[yoleen]!

可變長參數

有時候你並不知道輸入多少個參數,此時你可使用可變長參數。

//args是一個類型爲seq的參數。
def sum(args:Int*)={
  var result = 0
  for(elem <- args){
    result+=elem
  }
  result
}

雖然args是一個序列,但這種寫法是錯誤的。

val s = sum(1 to 5) //報錯

咱們不能將一個序列中的元素當作變長參數直接傳遞給方法,解決方法就是,將其看成參數序列進行處理,在序列後面追加 :_* 例如:

val s = sum(1 to 5:_*) //返回15

lazy

當val被聲明爲lazy時,它的初始化將被延遲,直到咱們首次對它取值。例如:

lazy val file = scala.io.Source.fromFile("文件路徑")
//在定義變量爲lazy後,只有咱們第一次使用這個變量時,file纔會被賦值。
//在初始化開銷較大的程序中,lazy十分有用。
//注意:lazy並不是沒有額外開銷,咱們每次訪問lazy變量時,
//會有一個函數已線程安全的方式檢查lazy變量有沒有被初始化。

碼字不易,若是以爲文章不錯,麻煩點下推薦。

相關文章
相關標籤/搜索