【Scala學習之一】 Scala基礎語法


環境
  虛擬機:VMware 10
  Linux版本:CentOS-6.5-x86_64
  客戶端:Xshell4
  FTP:Xftp4
  jdk1.8
  scala-2.10.4(依賴jdk1.8)
spark-1.6

Scala是一種混合功能編程語言,類似java,運行於JVM,集成面向對象編程和函數式編程的各種特性。
(1)Scala可以與Java互操作:它用scalac這個編譯器把源文件編譯成Java的class文件,從Scala中調用所有的Java類庫,也同樣可以從Java應用程序中調用Scala的代碼
(2)Spark是專為大規模數據處理而設計的快速通用的計算引擎,而spark就是scala編寫的。
(3)對比Groovy和Scala:Groovy的優勢在於易用性以及與Java無縫銜接,Scala的優勢在於性能和一些高級特性


一、數據類型


二、變量和常量
定義變量:var,值可修改;
定義常量:val,值不可修改

var a:Int=10
var a=10
val a=10

注意:
(1)scala 中一行代碼后可以寫“;”也可以不寫,會有分號推斷機制。多行代碼寫在一行要用分號隔開。
(2)a: Int ": Int" 是變量的類型,可以寫也可以不寫,不寫會自動推斷變量類型

三、訪問修飾符
私有的 private
受保護的 protected
有明確使用修飾符則自動歸為公共成員 Public


四、運算符
跟java差不多,但是沒有自增++、自減--運算符
https://www.yiibai.com/scala/scala_operators.html


五、流程控制
1、分支判斷

val age =18 
if (age < 18 ){
println("no allow")
}else if (18<=age&&age<=20){
println("allow with other")
}else{
println("allow self")
}

 

2、循環
(1)to和until 的用法(不帶步長,帶步長區別)

/**
* to和until
* 例:
* 1 to 10 返回1到10的Range數組,包含10
* 1 until 10 返回1到10 Range數組 ,不包含10
*/

println(1 to 10 )//打印 Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
println(1.to(10))//與上面等價,打印 Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

println(1 to (10 ,2))//步長為2,從1開始打印 Range(1, 3, 5, 7, 9)
println(1.to(10, 2)) //Range(1, 3, 5, 7, 9)

println(1 until 10 ) //不包含最后一個數,打印 Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
println(1.until(10))//與上面等價 Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

println(1 until (10 ,3 ))//步長為2,從1開始打印,打印Range(1, 4, 7)

 

(2)for
(2.1)for循環

for( i <- 1 to 10 ){
println(i)
}

 

(2.2)多層for循環

//可以分號隔開,寫入多個list賦值的變量,構成多層for循環
//scala中 不能寫count++ count-- 只能寫count+
var count = 0;
for (i <- 1 to 10; j <- 1 until 10) {
println("i=" + i + ",    j=" + j)
count += 1
}
println(count);

//例子: 打印小九九
for (i <- 1 until 10; j <- 1 until 10) {
if (i >= j) {
print(i + " * " + j + " = " + i * j + "    ")

}
if (i == j) {
println()
}

}

 

(2.3)for循環中可以加條件判斷,可以使用分號隔開,也可以不使用分號

//可以在for循環中加入條件判斷
for (i <- 1 to 10; if (i % 2) == 0; if (i == 4)) {
println(i)
}

 

(2.4)scala中不能使用count++,count—只能使用count = count+1 ,count += 1
(2.5)for循環用yield 關鍵字返回一個集合

var result = for (i <- 1 to 10) yield i;
println(result);//Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
result.foreach { x => println(x) }//增強for循環

 

(3)while循環,while(){},do {}while()

/**
* while 循環
*/
var index = 0
while (index < 100) {
println("第" + index + "次while 循環")
index += 1
}
index = 0
do {
index += 1
println("第" + index + "次do while 循環")
} while (index < 100)

 

六、類和對象
類:
class是scala中的類;
類可以傳參,傳參就有了默認的構造函數;
重寫構造,第一行要調用默認的構造類可以傳參;
class類屬性自帶getter ,setter方法;
使用class時要new ,並且new的時候,class中除了方法不執行,其他都執行;
同一個包下,class的名稱不能相同。

對象:
object是單例對象,相當於java中的工具類,可以看成是定義靜態的方法的類;
object不可以傳參數。另:Trait不可以傳參數;
使用object時,不用new;


注意:
(1)建議類名首字母大寫 ,方法首字母小寫,類和方法命名建議符合駝峰命名法。
(2)如果在同一個文件中,object對象和class類的名稱相同,則這個對象就是這個類的伴生對象,這個類就是這個對象的伴生類。可以互相訪問私有變量。

package com.wjy

class Person(xname: String, xage: Int) {
var name = Person.name
val age = xage
var gender = "m"
def this(name: String, age: Int, g: String) {
this(name, age)
gender = g
}

def sayName() = {
"my name is " + name
}

}

object Person {
var name="zhangtiantang";
def main(args: Array[String]): Unit = {

val person = new Person("wagnwu",10,"f")
println(person.age);
println(person.sayName())
println(person.gender)
}

}

 

七、函數

1、函數定義
(1)函數定義用def,函數的參數 要寫類型,不寫類型不可以。
(2)函數的返回值類型可以不寫,會自動推斷,但在遞歸函數中或者函數的返回值是函數類型的時候 不能省略
(3)scala會將函數體中最后一行計算的結果當做返回值返回
(4)可以寫“return”,寫了return要顯式的聲明方法體的返回類型。
(5)定義函數時,如果不寫“=”,那么無論方法體中最后一行計算的結果返回是什么,都會被丟棄,返回Unit
(6)函數體可以一行搞定,那么方法體的“{... ...} ” 可以省略不寫

def fun (a: Int , b: Int ) : Unit = {
   println(a+b)
 }
fun(1,1)
    
def fun1 (a : Int , b : Int)= a+b
    println(fun1(1,2)) 

 

2、遞歸函數

def fun2(num :Int) :Int= {
if(num ==1)
num
else 
num * fun2(num-1)
}
print(fun2(5))

 


3、包含參數默認值的函數
(1)默認值的函數中,如果傳入的參數個數與函數定義相同,則傳入的數值會覆蓋默認值。
(2)如果不想覆蓋默認值,傳入的參數個數小於定義的函數的參數,則需要指定參數名稱。

def fun3(a: Int = 10, b: Int) = {
println(a + b)
}
fun3(b = 2)     

 

4、可變參數個數的函數
 多個參數用逗號分開

def fun4(elements: Int*) = {
var sum = 0;
for (elem <- elements) {
sum += elem
}
sum
}
println(fun4(1, 2, 3, 4))

def fun5(elms: String*)={
//簡化1:foreach 下划線_就代表每一個元素
elms.foreach { println(_)}
//簡化2:foreach println后面不跟任何東西 即可打印每一個參數
elms.foreach { println}
}

fun5("a","b","c","d","e","f")

 

5、匿名函數
(1)有參匿名函數
(2)無參匿名函數
(3)有返回值的匿名函數
(4)可以將匿名函數返回給val定義的值--閉包
(5)匿名函數不能顯式聲明函數的返回類型

//有參數匿名函數
val value1 = (a: Int) => {
println(a)
}
value1(1)
//無參數匿名函數
val value2 = () => {
println("我愛wjy")
}
value2()
//有返回值的匿名函數
val value3 = (a: Int, b: Int) => {
a + b
}
println(value3(4, 4))

6、嵌套函數

def fun5(num: Int) = {
def fun6(a: Int, b: Int): Int = {
if (a == 1) {
b
} else {
fun6(a - 1, a * b)
}
}
fun6(num, 1)
}
println(fun5(5))

 

7、偏應用函數
偏應用函數是一種表達式,不需要提供函數需要的所有參數,只需要提供部分,或不提供所需參數。

def log(date: Date, s: String) = {
println("date is " + date + ",log is " + s)
}

val date = new Date()
log(date, "log1")
log(date, "log2")
log(date, "log3")

//想要調用log,以上變化的是第二個參數,用下划線表示,可以用偏應用函數處理
val logWithDate = log(date, _: String)
logWithDate("log11")
logWithDate("log22")
logWithDate("log33")

 

8、高階函數
函數的參數是函數,或者函數的返回類型是函數,或者函數的參數和函數的返回類型是函數的函數。

//函數的參數是函數
def f(v1: Int, v2: Int): Int = {
v1 + v2
}
def hightFun(f: (Int, Int) => Int, a: Int): Int = {
f(a, 100)
}
println(hightFun(f, 1))

//函數的返回是函數
//1,2,3,4相加
def hightFun2(a: Int, b: Int): (Int, Int) => Int = {
def f2(v1: Int, v2: Int): Int = {
v1 + v2 + a + b
}
f2
}
println(hightFun2(1, 2)(3, 4))

//函數的參數是函數,函數的返回是函數
def hightFun3(f: (Int, Int) => Int): (Int, Int) => Int = {
f
}
println(hightFun3(f)(100, 200))
println(hightFun3((a, b) => { a + b })(200, 200))
//以上這句話還可以寫成這樣
//如果函數的參數在方法體中只使用了一次 那么可以寫成_表示
println(hightFun3(_ + _)(200, 200))

 

9、柯里化函數
可以理解為高階函數的簡化

def fun7(a: Int, b: Int)(c: Int, d: Int) = {
a + b + c + d
}
println(fun7(1, 2)(3, 4))

 

八、閉包
閉包是一個函數,它返回值取決於在此函數之外聲明的一個或多個變量的值。

object Demo {
def main(args: Array[String]) {
println( "multiplier(1) value = " + multiplier(1) )
println( "multiplier(2) value = " + multiplier(2) )
}
var factor = 3
val multiplier = (i:Int) => i * factor
}

 

 

參考:
Scala開發環境安裝配置
Scala基礎語法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM