Scala教程
SCALA
第一章 Scala入門
1.1 概述
1.1.1 Scala簡介
Scala的全稱為Scalable Language,即“可伸縮的語言”, 其設計目標是希望伴隨著用戶的需求一起成長。 Scala是一門綜合了面向對象和函數式編程概念的靜態類型的編程語言, 它運行在標準的java平臺上,可以與所有的Java類庫無縫操作 Spark,Kafka等底層都是Scala編寫的1.1.2 Scala的發展
馬丁·奧德斯基 追求簡潔高效 決定將函數式編程語言的特點融合到JAVA中,由此發明了兩種語言pizza和scala JDK5.0泛型、增強for循環、自動類型轉換等都是從Pizza引入的新特性 JDK8.0的類型推斷、lambda表達式就是從Scala中引入的特性1.1.3 Scala和Java的關系
Scala基于JVM 參考了Java的思想,可以說是源于Java,Java的進階版1.1.4 Scala語言特點
Scala是面向對象的 每個值都是對象,每個方法都是調用。 Scala是函數式的 Scala是功能完整的函數式編程語言,函數式編程以兩大理念為指導:函數是一等公民程序中的操作應該將輸入值映射成輸出值,而不是當場修改數據。即方法不應該有副作用 以JVM為運行環境的融合語言 面向對象和函數式編程1.1.5 Scala的優點
與Java兼容 精簡的語法 高級語言特性 靜態類型1.2 Scala環境搭建
1.2.1 安裝jdk1.8
Spark3.0基于Scala2.121.2.2 安裝Scala插件
打開IDEA,依次點擊Files=>settings=>plungins選項卡,搜索Scala,安裝重啟即可1.2.3 創建Scala項目
在IDEA中依次點擊File=>New=>Project,然后選擇創建Scala-IDEA工程1.2.4 下載Scala SDK
在上一步中,此時看到Scala為空,依次點擊Create=>Download,選擇所需版本后, 點擊ok進行下載,下載完成點擊finish進入工程1.2.5 創建HelloWorld
在工程src目錄上右點擊New=>Scala Class創建 選擇Scala Object,輸入名稱完成創建1.2.6 切換Scala版本
在日常的開發中,由于對應軟件,如Spark版本的切換,可能導致需要切換Scala的版本,則 可以在Project Structures中的Global Libraries選項卡中進行切換1.3 Scala伴生對象
Scala編譯后生成兩個文件 一個.class文件,一個$.class文件 類叫做伴生對象的聲明類 對象叫做類的伴生對象 Hello.class 程序執行的入口類或者當前對象的伴生類 Hello$.class 當前伴生對象的所屬類 object 單例對象和伴生對象是為了解決刪除靜態static關鍵字之后,而且要實現靜態功能而設計的 基于對象來調用,實現完全面向對象1.4 關聯Scala源碼
按住CTRL鍵,~~,將Scala源碼下載下來1.5 官方編程指南
1.在線查看 2.下載解壓scala-docs-2.11.8.zip第二章 變量和數據類型
2.1 注釋
和Java一樣 單行注釋// 多行注釋/* */ 文檔注釋/****/ 代碼規范:使用Tab鍵Shift+tab縮進格式化:CTRL+alt+L運算符兩邊各加一個空格一行不超過80個字符 實例:/chapter2/Test01.scala2.2 變量和常量
Scala的變量分為兩種 var 可以被重新賦值 val 不可以修改 var i:Int=10 scala將類型放在后面,表示它的類型并不重要 程序員要關注的東西是變量的名稱,業務處理的邏輯 類型是計算機底層需要考慮的問題,跟代碼邏輯沒什么關系 Scala的編譯器是可以對類型自動推斷的 能使用常量的地方盡量不使用變量* 聲明變量時,類型可以省略,編譯器可以總動推導* 類型確定后,就不能修改,說明Scala是強數據類型語言* 變量聲明時,必須要有初始值* var修飾的可修改,val修飾的不可修改 實例:/chapter2/Test02.scala2.3 標識符和命名規范
2.4 字符串輸出
2.5 鍵盤輸入
2.6 數據類型
Scala中一切數據都是對象,都是Array子類2.6.1 整數類型
整型分類:
byte,short,int,long 分別是8位,16位,32位,64位2.6.2 浮點類型
2.6.3 字符類型
2.6.4 布爾類型
2.6.5 Unit類型
Unit表示空值,null類型只有一個實例值null nothing類型啥也沒有:有可能拋出異常,返回值就可以指定為nothing2.7 類型轉換
2.7.1 自動類型轉換
自動提升原則:當有多種類型的數值混合運算時,系統首先自動將所有的數據轉換成精度大的那種數據類型 低精度可以賦值給高精度,但反過來不行 (byte,short)和char之間不會自動相互轉換,若要轉換,則先轉換為int類型2.7.2 強制類型轉換
將數據由高精度轉換為低精度,就需要使用到強制類型轉換 強轉換顧好只針對最近的操作數有效,往往會使用小括號提高優先級2.7.3 數值類型和String類型
1.數值類型轉String val a:Int=12 val s:String=a+“” 2.String類型轉數值第三章 運算符
3.1 算術運算符
+字符串相加
val re1=10/3 println(re1) val re2:Double=10/3 println(re2) val re3:Double=10.0/33.2 關系運算符
==3.3 邏輯運算符
&& || ! 連接多個條件3.4 賦值運算符
Scala里面沒有++,--等 可以通過+=,-=等來實現3.5 位運算符
& | ^ ~ < < >> >>>3.6 Scala運算符本質
運算符的本質是一個對象的方法調用
val n1:Int=12 val n2:Int=13 println(n1.+(n2))第四章 流程控制
4.1 分支控制
if else 特別的地方: 有返回值,定義為當前分支最后一個語句的值。 val res=if(age>=18) "成年" else "未成年"4.2 嵌套分支
年齡18,12,6,35,604.3 Switch分支結構
4.4 for循環控制
####4.4.1范圍數據循環to
for循環的特性被稱為for推導式
4.4.2 范圍數據循環until
for(i <- 1 until 10)println(i) for(i<-Array(10,20,30))println(i)4.4.3 循環守衛
for(i<- -1 to 3 if i!=2)println(i)4.4.5 循環步長
//循環步長,by是一個方法,是Range中的一個方法,(1 to 10).by()for(i<-1 to 10 by 2)println(i)for(i<-13 to 30 by 3)println(i)for(i<-13 to 0 by -2)println(i)for(i<-1 to 10 reverse)println(i)//步長不能為0//含笑半步顛for(i<-1.0 to 10.0 by 0.5)println(i)4.4.6 嵌套循環
//循環嵌套for(i<-1 to 10;j<-1 to 3)println(i*j)4.4.7 循環引入變量
//循環引入變量for(i<- 1 to 10){val j=10-iprintln(i,j)}for(i<-1 to 10;j=10-i)println(i,j)//打印輸出九層妖塔for(i<-1 to 9;j=9-i){println(" "* j + "*"*(2*i-1))}4.4.8 循環返回值
val res=for(i<-1 to 10)yield i4.5 While 和 do…while循環控制
1,在Scala中不推薦使用while循環,while必須在外部定義變量,while沒有for循環的得到返回值用法 2.真正的函數式語言沒有循環的,4.6 循環中斷
Scala內部控制結構去掉了break和continue
// 1. 采用拋出異常的方式退出循環 try{for(i<-0 until 4){if(i==3){throw new RuntimeException}println(i)}}catch {case e:Exception=> //什么都不做}// 2. 為了簡化,使用Scala中的Breaks類的break方法,實現異常的拋出和捕捉Breaks.breakable(for(i<-1 to 4){if(i==3){Breaks.break();}println(i)})println("=============")import scala.util.control.Breaks._breakable(for(i<-1 to 4){if(i==3){break();}println(i)})第五章 函數式編程
1.面向對象編程
Scala語言是一個完全面向對象編程語言。萬物皆對象 對象的本質:對數據和行為的一個封裝2.函數式編程
函數式編程,解決問題時,將問題分解成一個一個的步驟,將每個步驟進行封裝(函數),通過調用 當成一個數學題的求解,所有的都是一個表達式求值的過程 真正的函數式編程語言里沒有變量,所有的值來了之后都是常量,所以在scala中能用val的地方就用val 解決問題的過程就是不停的求表達式的值的過程 真正的函數式編程的本質是映射表達式求值。 函數式編程,有一個非常好的特性,對于函數而言是不可變的,這就可以做一個分布式的處理 彼此之間沒有額外的影響5.1 函數基礎
5.1.1 函數的基本語法
def funcname(x:Int,y:Int):Unit={println(x+y)} 關鍵字 函數名稱 參數 返回類型 函數體5.1.2 函數的和方法的區別
函數:為完成某一功能的程序語句的集合,稱為函數 方法:類中的函數稱之為方法 object Test01 {def main(args: Array[String]): Unit = {//定義函數def sayHi(name:String):Unit={println("hi "+name)}//調用函數sayHi("gaio")//調用對象方法Test01.sayHi("gao")}//定義對象的方法def sayHi(name:String):Unit={println("hi hi "+name)}}5.1.3 函數定義
參數 返回值5.1.4 函數參數
1.可變參數 2.如果參數列表中存在多個參數,那么可變參數一般放置在最后 3.參數默認值,一般將有參數的默認值 //1.可變參數def f1(str:String*):Unit={println(str)}f1("alice")f1("alice","bob")//2.如果參數列表中存在多個參數,那么可變參數一般放置在最后def f2(str1:String,str2:String*):Unit={println(str1,str2)}f2("alice")f2("alice","bob")//3.參數默認值def f3(str:String="hi"):Unit={println(str)}f3()f3("hihihi")//4.帶名參數def f4(name:String="hi",age:Int):Unit={println(s"$age $name")}f4("bob",23)f4(age=24,name="hihanpi")f4(age=23)5.1.5 函數至簡原則
能省則省 至簡原則細節:
//函數至簡原則def f0(name:String):String={return name}println(f0("hi"))//1.return 可以省略,Scala會使用函數體的最后一行代碼作為返回值def f1(name:String):String={name}println(f1("hi1"))//2.如果函數體里面只有一行代碼,則可以省略花括號def f2(name:String):String=nameprintln(f2("hi2"))//3.返回值的類型如果能夠推斷出來,則可以省略(:和返回值類型一起省略)def f3(name:String)=name//4.如果函數體里有return,則返回類型不能省略def f4()={}//5.如果函數明確聲明Unit,則即使函數體中使用return關鍵字也不起作用def f5():Unit={return 1}println(f5())//6.Scala如果期望是無返回值類型,可以省略等號def f6(){//有時候被稱為過程println("hi")}//7.如果函數無參數,那么小括號可以省略,調用時小括號可以省略def f7(): Unit ={println("hi")}f7()f7//8.如果沒有參數列表,那么小括號可以省略,調用時小括號必須省略def f8:Unit={println("hi")}f8//9.如果我們不關心名稱,只關心處理邏輯,那么函數名def可以省略(name:String)=>{println("hi")} //匿名函數,lambda5.2 函數高級
5.2.1 高階函數
在Scala中,函數地位很高,一方面,我們在代碼的任何地方,可以聲明定義一個函數,非常靈活 函數作為一個表達式的值,可以有更加高階的用法:函數可以作為值傳遞函數可以作為參數傳遞函數可以作為函數返回值返回 val fun=(name:String)=>{println(name)} //匿名函數,lambdafun("hi")//定義一個函數,以函數作為參數輸入def f(func:String=>Unit)={func("hi")}f(fun)f((name:String)=>{println(name)})//匿名函數的簡化原則f((name:String)=>{println(name)})//1.參數的類型可以省略,會根據形參進行自動的推導f((name)=>{println(name)})//2.類型省略之后,發現只有一個參數,則圓括號可以省略;其它情況:沒有參數和參數超過1的永遠不能省略圓括號f(name=>{println(name)})//3.匿名函數如果只有一行,則大括號也可以省略f(name=>println(name))//4.如果參數只出現一次,則參數省略且后面參數可用_代替f(println(_))//5.如果可以推斷出,當前傳入的println是一個函數體,而不是調用語句,可以直接省略下劃線f(println)5.2.2 匿名函數
匿名函數沒有名字(x:Int)=>{函數體}
//實例操作,定義一個“二元運算”函數,只操作1和2兩個數,但是具體運算通過參數傳入def dualFunctionOneAndTwo(fun:(Int,Int)=>Int):Int={fun(1,2)}val add=(a:Int,b:Int)=>a+bval minus=(a:Int,b:Int)=>a-bprintln(dualFunctionOneAndTwo(add))println(dualFunctionOneAndTwo(minus))//匿名函數簡化println(dualFunctionOneAndTwo((a:Int,b:Int)=>a+b))println(dualFunctionOneAndTwo((a,b)=>a+b))println(dualFunctionOneAndTwo(_+_))println(dualFunctionOneAndTwo(_-_))println(dualFunctionOneAndTwo(-_+_)) //b-a5.2.3 高階函數案例
5.2.4 函數柯里化&閉包
5.2.5 遞歸
5.2.6 控制抽象
5.2.7 惰性函數
第六章 面向對象
Scala的面向對象和Java的面向對象思想和概念是一直的,類的概念,對象的概念 Scala又補充了很多的功能6.1 Scala包
package 包名 Scala包的作用-和Java一樣區分相同名字的類當類很多時,可以很好的管理控制訪問范圍6.1.1 包的命名
命名規則:只能包含數字,字母,小花仙,小圓點(分隔符),不能使用關鍵字,不能數字開頭 命名規范: com.公司名.項目名.業務模塊名.xxx6.1.2 包說明(包語句)
1.包名和源文件所在路徑不要求必須一致 2.花括號嵌套6.1.3 包對象
在Scala中可以為每個包定義一個同名的包對象, 定義在包對象中的成員,作為其對應包下所有class和object的共享變量,可以被直接訪問 package object name{}6.1.4 導包說明
和Java一樣,頂部導入 局部導入,什么時候用,什么時候import 通配符導入_ 給包中的類重新起名import java.util.{ArrayList=>JL} 導入相同包的多個函數import java.util.{HashSet,ArrayList} 屏蔽類import.java.util.{ArrayList=>_,_} 注意:Scala中三個默認導入:6.2 類和對象
類:可以堪稱一個模板 對象:表示具體的事物6.2.1 定義類
1.基本語法 [修飾符]類名6.2.2 屬性
6.3 封裝
6.1.5 訪問權限
Scala中默認訪問權限為public,但是Scala中沒有public關鍵字 private為私有權限,只在類的內部和伴生對象中可用 protected為受保護權限,Scala中受保護權限比Java中更嚴格,同類、子類可以訪問,同包無法訪問 private[包名]增加包訪問權限,包名下其它類也可以使用6.2.3 方法
6.2.4 創建對象
6.2.5 構造器
和Java一樣,Scala構造對象也需要調用構造方法,并且可以有任意多個構造方法 Scala類的構造器包括:主構造器和輔助構造器基本語法class 類名(形參列表){ //主構造器//類體def this(形參列表){//輔助構造器}def this(形參列表){//輔助構造器可以有多個}}說明:1.輔助構造器,函數的名稱this,可以有多個,編譯器通過參數的個數及類型來區分2.輔助構造方法不能直接構建對象,必須直接或間接調用主構造方法3.構造器調用其它的構造器,要求被調用構造器必須實例:/chapter6/Test04.scala6.2.6 構造器參數
說明:1.未使用任何修飾符,局部變量2.使用var 作為類的成員屬性使用,可以修改3.使用val 作為類只讀屬性使用,不能修改6.4 繼承和多態
基本語法:class 子類名 extends 父類名{ 類體 } Scala是單繼承 繼承的調用順序:先調用父類構造器>然后子類構造器 /*** 調用順序* 1.父類的主構造器被調用* 2.子類的主構造器被調用* 3.子類的輔助構造器被調用*/ 子類中如果要覆蓋父類中的屬性和方法,必須要加override關鍵字 在scala中,屬性和方法都是動態綁定的6.5 抽象類
6.5.1 抽象屬性和抽象方法
1.基本語法定義抽象類abstract class Person{}//通過關鍵字abstract標記抽象類定義抽象屬性 var|val name:String//一個屬性沒有初始化,就是抽象屬性定義抽象方法def hello():String //只聲明而沒有實現的方法,就是抽象方法說明:只要存在抽象屬性和抽象方法,那么這個類必須定義為抽象類定義了一個抽象類,可以不定義任何的抽象屬性和方法需要子類具體化之后創建 對象才可用 2.繼承&重寫如果父類為抽象類,那么子類需要將抽象的屬性和方法實現,否則子類也需要聲明為抽象類重寫非抽象方法血藥用override修飾,抽血抽象方法則可以不加override子類調用父類的方法使用super關鍵字子類對抽象屬性進行實現,父類抽象屬性可以用var修飾子類對非抽象屬性重寫,父類非抽象屬性只支持val類型,而不支持var因為var修飾的為可變變量,子類繼承之后就可以直接使用,沒必要重寫6.5.2 匿名子類
說明:和Java一樣,可以通過包含帶有定義或重寫的代碼塊的方式創建一個匿名的子類6.6 單例對象
scala語言是完全面向對象的語言,所以并沒有靜態的操作,也沒有靜態的概念。 但是為了能夠和Java語言交互,就產生了一種特殊的對象來模擬類對象,稱為單例對象。 若單例對象名與類名一致,則稱該單例對象這個類的伴生對象 這個類的所有靜態內容都可以放置在它的伴生對象中聲明 對于object定義的對象,全局只有一份,在底層,編譯后生成兩個字節碼文件6.6.1 單例對象語法
object Person{val contry:String="china" } 說明單例對象采用object關鍵字聲明6.6.2 apply方法
6.7 特質(trait)
6.7。1 特質聲明
6.7。2 特質疊加
6.7。3 特質疊加執行順序
6.7。4 特質自身類型
6.7。5 特質和抽象類的區別
6.8 擴展
總結
- 上一篇: 如何在嵌入式fpga系统下关闭pcap打
- 下一篇: 小程序在安卓手机时间格式显示英文的坑