1. 程式人生 > 其它 >Scala 變數與函式

Scala 變數與函式

變數

Scala語言中沒有原始資料型別,這一點和Java語言不同,在Scala中一切都是物件。以下是Scala語言中常見型別和型別間的繼承關係。

在Java中常見的基本型別在Scala中都被剔除了,Scala將值型別和引用型別分離。所有的數值變數型別都是 AnyVal的子類,這些變數的值都有字面值。對於一些物件型別的變數都是 AnyRef的子類。對於 AnyRef類下的變數(除String型別),一般不允許直接賦值字面量,都需要藉助 new關鍵建立。

變數宣告

Scala語言是一種可以做型別自動推斷的強型別的程式語言。變數的型別可通過編譯器在編譯的時候推斷出最終型別。因此Scala中宣告一個變數主需要告知編譯器該變數的值是常量還是變數,例如:例如宣告一個變數使用var即可,如果宣告的是一個常量使用val關鍵字。因此Scala中變數宣告的語法如下:var|val 變數名[:型別] = 變數值[:型別]

var a:Int = 1:Int
var b:Int = 1
var c = 1:Int
var d = 1

Scala所有的變數在宣告時可以省略型別,並不意味著Scala是一種弱型別的程式語言,程式一旦編譯後,型別固定,不可以更改。

數值轉換

scala> var i=1
i: Int = 1

scala> var b:Byte=i.asInstanceOf[Byte]
b: Byte = 1

scala> var b:Byte=i.toByte()
<console>:12: error: Byte does not take parameters
var b:Byte=i.toByte() scala> var b:Byte=i.toByte b: Byte = 1

使用者可以使用asInstanceOf[型別]這種方式在數值間轉換。該方式只適合型別相容的時候使用,如果型別不相容可以使用toInt、toChar、…等可以將常規引數自動轉換為數值型別。

scala> var sex="true"
sex: String = true

scala> sex.toBoolean
res2: Boolean = true

scala> sex.asInstanceOf[Boolean]
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
at scala.runtime.BoxesRunTime.unboxToBoolean(BoxesRunTime.java:
85) ... 32 elided10

陣列

宣告一個int型別的陣列:

val array:Array[Int] = Array(1,2,3)

元組

元組是在Scala程式語言中的一種特殊變數,該變數可以組合任意幾種型別的變數,構建一個只讀的變數型別。訪問元組的成員可以使用_元素下標訪問。(一個元組最多有22個元素)

//元組,只讀
var t:(String,Int)=("zhanghaonan",18)
print(t._1+t._2+"歲")

var t = (1,1,1,1,1,1,"adsf",1)
print(t._7)

分支迴圈

if

修飾的程式碼分支可以賦值給一個變數

var i:Int=new Random().nextInt(30)
var a = if (i<30){
    "唵"
}else if(i<60){
    "哞"
}else if(i<90){
    "咪"
}
println(a)

Break

Scala 語言中預設是沒有 break 語句,但是在 Scala 2.8 版本後可以使用另外一種方式來實現 break 語句。當在迴圈中使用 break 語句,在執行到該語句時,就會中斷迴圈並執行迴圈體之後的程式碼塊。Scala 中 break 的語法有點不大一樣,格式如下:

var loop=new Breaks
loop.breakable({
    do{
        i -= 1
        print(i+"\t")
        if(i==1) {
            loop.break()
        }
    }while(i!=0)
})

for

遍歷陣列

var array = Array(1,2,3,4,5)
for(i<-array){
    println(i)
}
var array = Array("苦","海","翻","起","愛","恨")
for(i<-0.to(array.length-1)){
    print(array(i))
}
var array=Array("a","b","c")
for( index <- 0 until array.length){
  print(array(index)+"\t")
}

for迴圈可以使用多個迴圈因子

//99乘法表
for(i<-1 to 9;j <- 1 to i){
    print(s"$i*$j="+(i*j)+"\t")
    if(i==j) println()
}

for迴圈巢狀if

for(i<-1 to 9;if(i%2==0 || i%3==0) ){
    print(s"$i\t")
}

陣列計算

var array=0 to 9
val results = for(i <- array;if(i%2==0)) yield i*i
for(i <- results){
    println(i)
}

模式匹配(類似Java中的switch-case)

模式匹配是檢查某個值(value)是否匹配某一個模式的機制,一個成功的匹配同時會將匹配值解構為其組成部分。它是Java中的switch語句的升級版,同樣可以用於替代一系列的 if/else 語句。

數值匹配

val x: Int = Random.nextInt(10)
var result= x match {
   case 0 => "zero"
   case 1 => "one"
   case 2 => "two"
   case 3 => "three"
   case 4 => "four"
   case _ => "other"
 }
 println(result)

型別匹配

var array=Array("zs",true,new Date(),1000.0)
var x=array(new Random().nextInt(array.length))
var result= x match {
   case v:String => "name"
   case v:Boolean => "sex"
   case x:Date => "birth"
   case x:Double => "salary"
   case _ => "未知"
  }
println(result)

函式

標準函式

def sum(x:Int,y:Int):Int={
    return x+y
}

//可以省略返回值型別
def sum(x:Int,y:Int)={
    x+y
}

可變長引數

def sum(args:Int*):Int={
    var sum:Int=0
    for(arg<-args){
        sum+=arg
    }
}

引數預設值

def hello(msg:String="hey",name:String="xiaoming"):Unit={
    print(msg+","+name)
}

內嵌函式

def factorial(x:Int)={
    def mulit(i:Int):Int={
      if(i > 0){
        i*mulit(i-1)
      }else{
        1
      }
    }
    mulit(x)
  }
// 等價
def factorial(x:Int):Int={
   if(x>0){
      x*factorial(x-1)
   }else{
      1
   }
 }

柯里化(Currying)

在電腦科學中,柯里化(Currying)是把接受多個引數的函式變換成接受一個單一引數的函式,並且返回接受餘下的引數的新函式的這種技術。

def sum1 (x:Int,y:Int):Int={x+y}
//sum1變成下面的形式

def add(x: Int)(y: Int): Int = {
  x + y 
}
var result = add(1)(_)
//下劃線“_” 作為第二引數列表的佔位符, 這個定義的返回值為一個函式,當呼叫時會給呼叫的引數加一
print(result(2))
//結果為3,在應用時應該使用這種形式:sum(1)(2)

add(1)(2) 實際上是依次呼叫兩個普通函式(非柯里化函式),第一次呼叫使用一個引數 x,返回一個函式型別的值,第二次使用引數y呼叫這個函式型別的值。

匿名函式

Scala中,函式可以沒有命名,此時函式被稱為匿名函式。可以直接定義匿名函式之後,將函式賦值給某個變數;也可以直接將定義的匿名函式傳入其他函式中。
Scala 中定義匿名函式的語法:(引數名:引數型別)=>函式體

var f:(Int,Int)=>Int = (x:Int,y:Int)=>{x*y}
print(f(4,5))
def a(x: Int, y: Int)(b: (Int, Int) => Int): Int = {
  b(x, y)
}
print(a(1,2)((i:Int,j:Int)=>i+j))

高階函式的型別推斷

高階函式可以自動推斷出引數型別,而不需要寫明型別;而且對於只有一個引數的函式,還可以省去其小括號;如果僅有一個引數在右側的函式體內只使用一次,則還可以將接收引數省略,並且可以引數用_來替代。

函式和變數

定義一個是變數的函式

var f:(Int,Int)=>Int = (x:Int,y:Int)=>Int

宣告一個函式

sum:(Int,In)=>Int = (x,y)=>{x+y}