條件運算式
與java/c++不同的是,scala中 if / else語法是有回傳值的,這個值就是跟在if / else 之后的最后一個運算式的值,
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型別,
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回圈是這樣的:
// 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編譯器能通過回傳值推斷出回傳型別,
對于遞回函式我們必須要指定回傳型別,例如:
// 遞回求字串中的所有字符的乘積,
def recursive(s:String,i:Int):Long={
if(i<s.length){
recursive(s,i+1)*s(i).toInt
}else{
1
}
}
默認引數和帶名引數
在函式定義時可以帶上初始值,如:
def sayHello(name:String,s:String="hello,",left:String="[",right:String="]")={
s+left+name+right
}//輸入name="yoleen" 將輸出 hello,[yoleen]
對于引數較多的函式,帶名引數能顯得程式更加易讀,
注意引數并不需要跟引數串列順序一致,
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變數有沒有被初始化,
碼字不易,如果覺得文章不錯,麻煩點下推薦,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/412.html
標籤:Scala
上一篇:一起學scala--基礎
