大數據課程J2——Scala的基礎語法和函數

文章作者郵箱:yugongshiye@sina.cn? ? ? ? ? ? ? 地址:廣東惠州

?▲ 本章節目的

??掌握Scala的基礎語法;

? 掌握Scala的函數庫;

一、Scala 基礎語法一

1. 概述

語句

說明

示例

var

用來聲明一個變量,
變量聲明后,在程序執行過程中可以被修改。

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

??? var var1=100

??? var var2:Int=100

?? //變量修改

??? var2=200;

??? var3="world";

val

用來聲明一個常量,
一旦被賦值就不能再進行修改

?

//定義常量,但不允許修改常量

val vall = 100;

//常量修改將報錯

vall = 200;

操作符

scala中操作符即方法,方法即操作符

所以 可以認為 scala中并沒有傳統意義上的操作符 所有的操作符都是方法 所有的方法也都可以像操作符一樣去使用

1.?算術運算符

+ - * / %

2.?關系運算符

==? !=? >?? <?? >=? <=== > < >= <=

3.?邏輯運算符

&&? ||? !

4.?位運算符

~? &? |? ^? <<?? >>?? >>>

5.?賦值運算符

=? +=? -=?? *=?? /=?? %=

2. 算術運算符

下表列出了Scala支持的算術運算符。

假定變量A為10,B為20:

運算符描述實例
+加號A + B 運算結果為 30
-減號A - B 運算結果為 -10
*乘號A * B 運算結果為 200
/除號A / B 運算結果為 2
%取余A % B 運算結果為 0

3. 關系運算符

下表列出了Scala支持的關系運算符。

假定變量A為10,B為20:

運算符描述實例
==等于( A == B ) 運算結果為 false
!=不等于( A != B ) 運算結果為 true
>大于( A > B ) 運算結果為 false
<小于( A < B ) 運算結果為 true
>=大于等于( A >= B ) 運算結果為 false
<=小于等于( A <= B ) 運算結果為 true

4. 邏輯運算符

下表列出了Scala支持的關系運算符。

假定變量A為1,B為0:

運算符描述實例
&&邏輯與( A && B ) 運算結果為 false
||邏輯或( A || B ) 運算結果為 true
!邏輯非! ( A && B ) 運算結果為 true

5. 位運算符

位運算符用來對二進制位進行操作,~,&,|,^ 分別為取反,按位與與,按位與或,按位與異或運算,如下實例:

運算符描述實例
&按位與運算符(a & b) 輸出結果12,二進制解釋:0000? 1100
|按位或運算符(a | b) 輸出結果61,二進制解釋:0011? 1101
^按位異或運算符(a ^ b) 輸出結果49,二進制解釋:0011? 0001
~按位取反運算符(~a) 輸出結果-61,二進制解釋:1100? 0011, 在一個有符號二進制數的補碼形式。
<<左移動運算符a<<2 輸出結果240,二進制解釋:1111? 0000
>>右移動運算符a>>2 輸出結果15,二進制解釋:0000? 1111
>>>無符號右移a>>>2 輸出結果15,二進制解釋:0000? 1111

6. 賦值運算符

一下列出了Scala語言支持的賦值運算符:

運算符描述實例
=簡單的賦值運算,指定右邊的操作數賦值給左邊的操作數。C = A + B 將 A + B 的運算結果賦值給 C
+=相加后再賦值,將左右兩邊的操作數相加后再賦值給左邊的操作數。C += A 相當于 C = C + A
-=相減后再賦值,將左右兩邊的操作數相減后再賦值給左邊的操作數。C -= A 相當于 C = C - A
*=相乘后再賦值,將左右兩邊的操作數相乘后再賦值給左邊的操作數。C *= A 相當于 C = C * A
/=相除后再賦值,將左右兩邊的操作數相除后再賦值給左邊的操作數。C /= A 相當于 C = C / A
%=求余后再賦值,將左右兩邊的操作數求余后再賦值給左邊的操作數。C %= A 相當于 C = C % A

二、Scala 基礎語法二

語句

說明

示例

if……else

if……else 判斷

if是具有返回值的,if判斷后,將執行代碼的最后一個表達式的值返回作為整個if執行后的結果。

??? //一個簡單的示例

??? var var1=10;

??? if(var1<100){

????? println("小了")

??? }else{

????? println("大了")

??? }

???

?? ?//根據scala函數式編程風格,建議做如下更改

??? //盡量使用常量

??? val val1=10;

?? ?//if……else最后一行的值是返回值,可省略return

??? val result=

???????? if(val1<100){

?????????? "小了";

???????? }else{

?????????? "大了";

???????? }

??? print(result)

??? //也可以簡化成下面的形式

??? val val2=10;

??? println(if(val2<100)"小了"else"大了");

while

和java中用法相同

??? //一個簡單的例子

??? val val1=List(1,2,3,4);

??? var index=0;

??? while(index<val1.size){

????? println(val1(index));

????? index+=1;

??? }

for

scala中的for要比java的for強大,使用很頻繁,需要熟練掌握。

?

?? //生成一個1~100的區間,區間類型是range

??? val val1=1 to 100;

???

??? //循環遍歷并打印

??? for(num <-val1){

????? println(num)

??? }

???

??? //支持條件過濾

??? for(num<-val1;if num>50){

????? println(num)

??? }

???

??? //支持多條件過濾

??? for(num<-val1;if num>50;if num%2==0;if num<90)

????? println(num)

?? //也可以寫成下面的形式

??? for(num<- 1 to 100;if num>50&&num<90&&num%2==0){

????? println(num)

??? }

try catch finally

scala中繼承了java的異常機制

import java.lang

try {

????? throw new RuntimeException("error");

??? }catch {

?????? case t: NullPointerException => t.printStackTrace();("空指針異常");

????? case t: Exception=>t.printStackTrace();println("其他異常");

??? }finally {

????? println("資源釋放")

??? }

match

scala中的match類似于其他語言的switch

//一個簡單的例子

//match匹配到case后,執行case對應的內容,然后退出match,于java不同的是,不需要寫break

??? val val1="bbb";

??? val1 match {

????? case "aaa" =>println("1");

????? case "bbb" =>println("2");

????? case? _ =>println("3");

??? }

???

? ??//此外,match可以帶有返回值

??? val result=val1 match{

????? case "aaa" =>1

????? case "bbb" =>2

????? case? _ =>3

??? }

break

continue

scala中沒有break和continue語句,需要通過另外的形式來實現

import util.control.Breaks._

object Demo12 {

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

????

??? ?//實現break

? ???breakable(

?? for(i <- 1 to 10){

?????? if(i==8){

????????? break();

?????? }else{

???????? println(i);

?????? }

???? }

????? ???)

????

??? ?//實現continue

???? for(i<-1 to 10){

?????? breakable(

??????? if(i==8){

????????? break;

??????? }else{

????????? println(i);

??????? }

???? ??)

???? }

????

????

? }

}

三、Scala函數上篇

1. 函數聲明

scala 函數通過 def 關鍵字定義,def前面可以具有修飾符,可以通過private、protected來控制其訪問權限。

注意:沒有public,不寫默認就是public的。 此外也可跟上override,final等關鍵字修飾。

2. 函數返回值

1. 函數體中return關鍵字往往可以省略掉,一旦省略掉,函數將會返回整個函數體中最后一行表達式的值,這也要求整個函數體的最后一行必須是正確類型的值的表達式。

2. 大部分時候scala都可以通過 =符號 來自動推斷出返回值的類型,所以通常返回值類型聲明可以省略。

但是注意:如果因為省略了返回值類型造成歧義,則一定要寫上返回值聲明。

3. 如果函數體只有一行內容,則包裹函數體的大括號可以省略

4. 如果返回值類型是UNIT,則另一種寫法是可以去掉返回值類型和等號,把方法體寫在花括號內,而這時方法內無論返回什么,返回值都是 UNIT。????????????????

格式:[private/protected] def 函數名(參數列表):返回值聲明 = {函數體}

示例:

? //方法的返回值為空

? def f1():Unit={

???? println("hello scala");

? }

? //等價于f1()方法,注意:如果函數沒有=號,無論函數體里的返回值是什么,函數的返回值都是Unit

? def f2(){

??? println("hello scala");

? }

? //定義方法參數類型,返回值類型,及返回值

? def f3(a:Int,b:Int):Int={

??? a+b;

? }

??//scala可自行推斷返回值類型,所以可省略返回值類型

? def f4(a:Int,b:Int)={

??? a+b;

? }

? //如果函數體只一行內容,可以省了花括號

? def f5(a:Int,b:Int)=a+b

? //注意下面這種形式,因為沒有=號,所以函數的返回值是Unit,即()

? def f6(a:Int,b:Int){

??? a+b

? }

3. 默認參數

代碼示意:

object Demo21 {

? def f1(a:String,b:String="[",c:String="]")={

??? b+a+c

? }

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

??? print(f1("hello"))//將打印:[hello]

? }

}

4. 函數的種類

1.成員函數

2.本地函數(內嵌在函數內的函數)

3.函數值(匿名函數)

4.高階函數

成員函數: 函數被使用在類的內部,作為類的一份子,稱為類的成員函數

示例:

object Demo15 {

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

??? val p=new Student();

??? p.eat();

??? p.study();

? }

? // eat() 和study()屬于 類Student的成員函數

? class Student{

??? def eat(){

????? println("吃飯")

??? }

??? def study(){

????? println("學習")

??? }

? }

}

本地函數:函數內嵌的函數稱為本地函數,這樣的函數外界無法訪問

示例:

object Demo16 {

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

??? val p=new Student();

??? p.eat("肉");

? }

? class Student{

??? def eat(food:String){

??? ??//cook函數內嵌在eat函數里,這樣的函數稱之為本地函數

????? def cook(food:String):String={

??????? "做熟了的"+food;

????? }

????? println("吃"+cook(food));

??? }

? }

}

函數值 - 匿名函數:

示例:

??? def f1(a:Int,b:Int):Int={a+b};

??? //等價于上式的函數

??? (a:Int,b:Int)=>{a+b};

??? //如果函數體只有一行代碼,可以省去大括號

??? (a:Int,b:Int)=>a+b;

? ??//如果函數參數列表只有一個參數,小括號有可以省略

??? a:Int=>a+1;

??? //如果函數的參數類型可以被推測,則可以省略類型值

??? //(a,b)=>a+b

??? def f1(a:Int,b:Int):Int={a+b};

? ??//可以將f1()函數賦值給f2常量

??? val f2=f1(_,_);

??? //可以將f1()函數賦值給f3變量,f3可以更改此函數

??? var f3=f1(_,_);

??? f3=(a:Int,b:Int)=>a*b;

??? //也可以這樣寫

??? val f4=(c:Int,d:Int)=>{c+d}

? ??//注意,下面的寫法是將f1的函數值復制給f5,而不是函數賦值給f5

??? val f5=f1(2,3)

四、Scala函數下篇

1. 高階函數:

高階函數(Higher-Order Function)就是操作其他函數的函數。

Scala 中允許使用高階函數, 高階函數可以使用其他函數作為參數,或者使用函數作為輸出結果。

示例1:

object Demo01 {

? //定義了compute函數,a,b和f函數? 三個參數。其中f函數未做實現。

? //我們的目的是對傳入的a和b參數利用 f函數做運算,但是具體是什么運算需要由用戶自己來指定。

? def compute(a:Int,b:Int,f:(Int,Int)=>Int):Int={

?? f(a,b)

? }

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

??? val f1=(a:Int,b:Int)=>{a+b}

??? val f2=(a:Int,b:Int)=>{a*b}

??? val f3=(a:Int,b:Int)=>{a-b}

??? val f4=(a:Int,b:Int)=>{a/b}

??? //由下式可以看出,scala中,函數可以當做參數進行傳遞和調用

??? val result=compute(2,3,f1)

? ??//下式等價于上式

??? //val result=compute(2,3,(a,b)=>{a+b})

? }

}

示例2

object Demo02 {

??//定義了一個函數,作用是將用戶處理后的字符串結果進行打印輸出

? def handleString(a:String,f:(String)=>String){

??? println("處理完后的字符串為:"+ f(a))

? }

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

??? val a="hello scala";

??? handleString(a,(a)=>{a});

??? handleString(a,(a)=>{a.substring(6)});

??? handleString(a,(a)=>{a.concat(" 1706")})

? }

}

占位符:占位符指的是scala中的下劃線_ ,可以用它當作一個或多個參數來使用。

使用_占位符的前提要求:每個參數在函數僅出現一次。

使用下劃線時,如果類型可以自動推斷出,則不用聲明類型。如果無法自動推斷類型,則在下劃線后自己來顯示聲明類型即可。

示例1

object Demo03 {

? def compute(a:Int,b:Int,f:(Int,Int)=>Int):Int={

?? f(a,b)

? }

? def handleString(a:String,f:(String)=>String){

??? println("處理完后的字符串為:"+ f(a))

? }

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

??? val message="hello scala";

??? //這樣用占位符會報錯

??? //handleString(message,(_)=>{_.substring(6)})

??? //應改為下面的寫法

??? handleString(message,{_.substring(6)})

?? ?//如果函數體只有一行代碼,則還可以將大括號去掉

???? handleString(message,_.substring(6))

?? ?//compute的代碼可簡化如下?

??? compute(2,3,_+_)

??? compute(2,3,_*_)

??? compute(2,3,_-_)

?? ?//??? 此外

??? //??? val f1=(a:Int,b:Int)=>{a+b}

??? //??? 等價于下式:

??? //??? val f1=(_:Int)+(_:Int)

??? //??? compute(2, 3, f1)

??? //再來看一個例子

??? val list=List(1,3,5,7,9)

??? list.foreach { x =>print(x) }

??? list.foreach { _ =>print(_) }

??? list.foreach { print(_) }

??? list.foreach { x => x*2 }

??? list.foreach { _*2 }

? }

}

2. 遞歸函數

示例1:用遞歸方式實現斐波那契數列

?//0? 1?? 1?? 2? 3? 5? 8?? 13

?def f2(n:Int):Int={

if(n==0) return 0

if(n==1) return 1

else f2(n-1)+f2(n-2)

?}??

五、練習題

1.針對下列Java循環編寫一個Scala版本:

for(int i=10;i>=0;i–)

???? System.out.println(i);

2.編寫一個函數countdown(n:Int),打印從n到0的數字

3.編寫函數計算x的n次方,其中n是整數,要考慮等n是0,正偶數,正奇數,負數這幾種情況。

比如當x=2時,此函數要算出 2^4,2^3,2^0,2^(-1)對應的值

mi(x:Int,n:Int):Double={??? }

mi(2,10)=1024

mi(2,-1)=0.5

4.編寫一個循環,將整數數組中相鄰的元素置換

Array(1,2,3,4,5,6)

得到的結果:214365

5.創建一個Map,包含一些你想要的一些裝備,以及他們的價格。然后通過yield 構建另一個Map映射,采用同一組鍵,但是價格上打9折

比如定義一個Map:

var m1=Map("book"->10,"gun"->100,"ipad"->1000)?

則輸出的新map(m2)為:Map("book"->9,"gun"->90,"ipad"->900)?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38640.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38640.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38640.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java面試題(16):Mysql一致性視圖是啥時候建立的

1 演示錯誤案例 先給大家來一個錯誤演示。 我們打開兩個會話窗口&#xff0c;默認情況下隔離級別是可重復讀&#xff0c;我們來看下&#xff1a; 首先在 A 會話中查看當前 user 表&#xff0c;查看完成后開啟事務&#xff1a; 可以看到id3的數據sex是男。 接下來在 B 會話中…

K8S系列一:概念入門

寫在前面 本文組織方式&#xff1a; K8S的架構、作用和目的。需要首先對K8S整體有所了解。 K8S是什么&#xff1f; 為什么是K8S&#xff1f; K8S怎么做&#xff1f; K8S的重要概念&#xff0c;即K8S的API對象。要學習和使用K8S必須知道和掌握的幾個對象。 Pod 實例 Volume 數…

php錯誤類型與處理

1 語法編譯錯誤&#xff0c;少了分號&#xff0c;這是系統觸發的錯誤&#xff0c;不需要我們去管。 2 錯誤類型有四種&#xff1a;error致命錯誤&#xff0c;代碼不會往下運行&#xff1b;warning&#xff1a;提醒錯誤&#xff0c;會往下運行&#xff0c;但是會有意想不到的結果…

【C++學習】STL容器——stack和queue

目錄 一、stack的介紹和使用 1.1 stack的介紹 1.2 stack的使用 1.3 stack的模擬實現 二、queue的介紹和使用 2.1 queue的介紹 2.2 queue的使用 2.3 queue的模擬實現 三、priority_queue的介紹和使用 3.1 priority_queue的介紹和使用 3.2 priority_queue的使用 3.4 p…

JVM---理解jvm之對象已死怎么判斷?

目錄 引用計數算法 什么是引用 可達性分析算法&#xff08;用的最多的&#xff09; 引用計數算法 定義&#xff1a;在對象中添加一個引用計數器&#xff0c;每當有一個地方引用它時&#xff0c;計數器值就加一&#xff1b;當引用失效時&#xff0c;計數器值就減一&#xff1…

國內外醫療器械政策法規網站集合

隨著醫療技術的不斷發展&#xff0c;醫療器械在現代醫療中扮演著重要的角色。為了確保醫療器械的安全性、有效性和質量&#xff0c;各國紛紛制定了一系列的政策法規來監管醫療器械的研發、生產、銷售和使用。這些政策法規的制定和實施對于保障公眾健康、促進醫療器械產業的健康…

docker--------介紹、常用命令,國內源配置

1 docker 國內源配置 # 鏡像&#xff1a;一堆文件 -目前從遠程倉庫下載的&#xff1a;https://hub.docker.com/ -鏡像有很多人提供&#xff1a;官方提供&#xff0c;第三方提供 -鏡像--》更新--》Tag不同版本 -centos:latest 最新 -docker pull 能找到…

舊版本docker未及時更新,導致更新/etc/docker/daemon.json配置文件出現docker重啟失敗

一、背景 安裝完docker和containerd之后&#xff0c;嘗試重啟docker的時候&#xff0c;報錯如下&#xff1a; systemctl restart dockerJob for docker.service failed because the control process exited with error code. See “systemctl status docker.service” and “…

學習ts(一)數據類型(基礎類型和任意類型)

運行 起步安裝 npm install typescript -g 運行tsc index.ts生成對應的js文件&#xff0c;然后使用node index.js執行js文件 為了方便運行還可以安裝插件&#xff0c;ts-node index.ts運行即可 npm i ts-node -g npm init -y npm i types/node -D基本數據類型 // 1.字符…

探索不同類型的代理服務器 (代理 IP、socks5 代理)及其在網絡安全與爬蟲中的應用

1. 代理服務器簡介 代理服務器是一臺充當中間人的服務器&#xff0c;它在客戶端與目標服務器之間傳遞網絡請求。代理服務器在不同層級上可以執行不同的任務&#xff0c;包括緩存、過濾、負載均衡和隱藏客戶端真實IP地址等。在網絡安全和爬蟲領域&#xff0c;代理服務器具有重要…

ARM(匯編指令)

.global _start _start:/*mov r0,#0x5mov r1,#0x6 bl LoopLoop:cmp r0,r1beq stopsubhi r0,r0,r1subcc r1,r1,r0mov pc,lr*/ mov r0,#0x1mov r1,#0x0mov r2,#0x64bl Loop Loop:cmp r0,r2bhi stopadd r1,r1,r0add r0,r0,#0x01mov pc,lr stop:B stop.end

現有的vue3+ts+vite項目集成electron

效果圖 什么時Electron Electron是使用JavaScript,HTML和CSS構建跨平臺的桌面應用程序框架。 Electron兼容Mac、Windows和Linux,可以構建出三個平臺的應用程序。 現有的vue3項目集成Electron 安裝依賴 原來有一個vue3+ts+vite+pnpm的項目,其中sub-modules是子項目,web是…

Monge矩陣

Monge矩陣 對一個m*n的實數矩陣A&#xff0c;如果對所有i&#xff0c;j&#xff0c;k和l&#xff0c;1≤ i<k ≤ m和1≤ j<l ≤ n&#xff0c;有 A[i,j]A[k,l] ≤ A[i,l]A[k,j] 那么&#xff0c;此矩陣A為Monge矩陣。 換句話說&#xff0c;每當我們從矩陣中挑…

全面梳理Python下的NLP 庫

一、說明 Python 對自然語言處理庫有豐富的支持。從文本處理、標記化文本并確定其引理開始&#xff0c;到句法分析、解析文本并分配句法角色&#xff0c;再到語義處理&#xff0c;例如識別命名實體、情感分析和文檔分類&#xff0c;一切都由至少一個庫提供。那么&#xff0c;你…

地理數據的雙重呈現:GIS與數據可視化

前一篇文章帶大家了解了GIS與三維GIS的關系&#xff0c;本文就GIS話題帶大家一起探討一下GIS和數據可視化之間的關系。 GIS&#xff08;地理信息系統&#xff09;和數據可視化在地理信息科學領域扮演著重要的角色&#xff0c;它們之間密切相關且相互增強。GIS是一種用于采集、…

歐拉函數和最大公約數

分析&#xff1a;如果兩個數的最大公約數是一個質數p&#xff0c;那么這兩個數都除以p&#xff0c;得到的兩個數的最大公約數一定是1. 反證法&#xff1a;如果得到的兩個數的最大公約數不是1&#xff0c;那么把此時的最大公約數乘以上邊的最大公約數&#xff0c;得到的一定比上…

文件操作 和 IO

目錄 ?編輯一、認識文件 1、文件路徑 2、其它知識 二、Java 中操作文件 三、文件內容的讀寫 1、Reader 2、InputStream 3、輸出 一、認識文件 文件是在硬盤上存儲數據的一種方式&#xff0c;操作系統幫我們把硬盤的一些細節都封裝起來了 我們只需要了解文件相關的一些…

【前端 | CSS】滾動到底部加載,滾動監聽、懶加載

背景 在日常開發過程中&#xff0c;我們會遇到圖片懶加載的功能&#xff0c;基本原理是&#xff0c;滾動條滾動到底部后再次獲取數據進行渲染。 那怎么判斷滾動條是否滾動到底部呢&#xff1f;滾動條滾動到底部觸發時間的時機和方法又該怎樣定義&#xff1f; 針對以上問題我…

數據集成革新:去中心化微服務集群的無限潛能

在當今數據密集型的業務環境下&#xff0c;傳統的集中式架構已經難以滿足高可用性和高并發性的要求。而去中心化微服務集群則通過分散式的架構&#xff0c;將系統劃分為多個小型的、獨立部署的微服務單元&#xff0c;每個微服務負責特定的業務功能&#xff0c;實現了系統的高度…

centos系統kubeadm安裝K8S_v1.27.x容器使用docker(K8S_v1.24版本以后依然使用docker容器管理)

kubeadm安裝K8S_v1.27.x容器使用docker 按照需要的文檔點擊這里下載 一.環境部署 1.1基礎環境配置 主機IP 主機名規劃 192.168.186.128 k8s-master01 192.168.186.129 k8s-node01 192.168.186.130 k8s-node02 1.2修改機器名稱 #永久修改主機名 hostnamectl set-hostname …