当前位置: 首页 > news >正文

Scala基础语法

1.基本规范

     1. 通常一行一条命令,末尾无需添加分号

     2.一行包含多条命令,两两之间用分号隔开,建议非特殊语法不允许主动这样写代码

     3.可以在过程中【导包】,过程中定义函数,也可以在Object外部【导包】。

2.基本语法

必知点

一:scala中的下划线( _ )

**1、**详细讲解:

=> 下划线(_)在scala中是占位符,可以表示【任意内容

**2、**应用场景:

import package._	相当于 java *  【导包】
case _				相当于 default	【模拟匹配】

**3、**基于下划线的简易传参语法:

//参数占位符,参数列表中每个参数可以使用一条下划线
def cal(func:(Int,Int)=>Int,a:Int*)={
    var sum = 0
    for (elem <- a) {
        sum = func(sum,elem)
    }
    sum
}
// 下面两种写法的效果相同
val rst = cal(_ + _, 1, 2, 3, 4, 5)
val rst = cal((a,b)=>a+b, 1, 2, 3, 4, 5)

二:元组 TupleN

基本规则
基本格式:TupleN[T1,T2,T3,...]
讲解:
	N:1~22,表示能存放数量 => 最多可放22个
	T:泛型
举例:
	Tuple2("java", 80)
元组类型的表达: 
	推荐写法:syntactic suger 语法糖
		(String,Int) <=> Tuple2[String,Int]
注意事项:为避免冲突,需说明括号()的表示
() 可表示:
	1.元组 val tuple2 = ("java",88)
	2.数组下标提取 array(0)
	3.方法的参数列表 method(p1,...,pn)
二元组的声明与初始化
val tuple2 = ("java",88)						// 实际应用:最简语法 ✔
val tuple2: (String, Int) = ("java", 88)		// 初学推荐写法 ✔
val tuple2: Tuple2[String, Int] = Tuple2("java", 88)	//完整学法
元组的使用

元组值的获取

val tuple2: (String, Int) = Tuple2("java", 88)
val value1 = tuple2._1  // 获取元组第一个值
val value2 = tuple2._2  // 获取元组第二个值
println(s"${value1}  ${value2}")
----------------------------------------
java  88
----------------------------------------

迭代器遍历

val tp = (1,"good",12.34f,true)
val iterator: Iterator[Any] = tp.productIterator //迭代器
iterator.foreach(println)
----------------------------------------
1
good
12.34
true
----------------------------------------

三:Option[T] 【常见】

1.使用
	val opt:Option[T] = ...
	val rst = opt.getOrElse(default:T)
	得到的两个值:默认值【没有】或者有效值【有】
2.设计
	None extends Option
	Some extends Option
3.案例
	def add(a:Int,b:Int):Option[Int] = {
      	val sum = a + b
      	if(sum>100){
        	None
      	}else{
        	Some(sum)
      	}
    }
    val opt1: Option[Int] = add(65, 55)
    val rst2: Int = opt1.getOrElse(-1)
    println(rst2)
	--------------------------------
	-1
	--------------------------------

1、变量与常量

变量

:基本格式

var 变量名[:数据类型] =

:特别说明

      **1、**创建变量:必须赋初值

      2、可以不指定变量的具体类型,如 var a = 5,则变量的类型由【首次】赋值的值【类型】决定且锁定。

      3、若声明时已指定变量类型,如 var a:String = “hello” ,则类型不可更改

常量

:基本格式

//创建常量且初始化后,常量的类型和值都将锁定,不可更改
val 变量名[:数据类型] =

:特别说明

      **=>**创建常量且初始化后,常量的类型和值都将锁定,不可更改。

2、数据类型

2.1类型体系

Scala当中,总体的体系呈现“菱形”分布。

类型体系图的解读:

1Any是所有类型的父类,Nothing是所有类型的子类。
2、在基本类型【AnyVal】中,主要有以下类型:
		Unit(≈void),Boolean,Byte,Short,Int,Long,
		Float,Double,BigInt,BigDecimal
3、在引用类型【AnyRef】中,主要有以下类型:
		String,集合(List,Map,Set...),数组,自定义类,对象....

2.3类型别名

:基本格式

type 别名 = 类型Type

:案例

type t = String
var str:t = "hello world!"
println(str)
-------------------------------
hello world!
-------------------------------

:特别说明

类型别名的主要作用:简化复杂的类型名称。

一般情况下不建议使用

3、运算符

赋值运算符: =  +=  -=  *=  /=  %=

算术运算符: +  -  *  /  %	【没有 ++ --】

关系运算符: >  >=  <  <=  ==  != 

逻辑运算符: &&  ||  !
3.1运算符重载

从语法上来说scala是没有运算符的。Scala的运算符实际上是方法名,如1 + 2实际上就是1.+(2)。我们可以将之视为运算符,是因为在Scala中,如果方法的参数小于等于1个的话,那么“.”和括号就都是可选的。
案例val str = obj + param 等同于 val str = obj.+(param…)

4、程序逻辑

4.1表达式

:在Scala中一切皆为表达式
//【声明时】就会执行,即:无论如何都会将{}内的内容输出来
var b[:Int] = {
  println("initialize variable b")
  5*5
}
println(b)
----------------------------------
initialize variable b
25
----------------------------------
:惰性表达式:特殊的表达式。
//【使用时】才会执行,即:只有在使用时,才会将{}内的内容输出来
var a = 5
lazy val c ={
  println("initialize variable c")
  a*Math.PI
}
println(c)
三:中置表达式

注意点:方法的参数【只有一个参数】才可以使用中置表达式

1:左右闭

基本语法

// >= START && <= END
val NAME = START to END [by STEP]  // STEP缺省默认增值为1

案例

// >=1 && <=10
val range = 1 to 10

2:左闭右开

基本语法

// >= START && < END
val NAME = START until END [by STEP]  // STEP缺省默认增值为1

案例

// >=1 && <10
val range = 1 until 10

4.2分支

:基本语法

if...else if...else...

:案例

//格式化:s""   raw""   f""
val age = 15
if (age >= 18){
  //${}中的{}用于锁定边界
  println(s"你已经>=${age},成年了")
}else{
  println(s"还未成年,你才$age")
}

4.3类三元运算

:基本语法

val str = if(条件) "..." else "..."

:案例

val age = 12
val str = if(age>=18) "成年" else "未成年"
println(str)
----------------------
未成年
----------------------

4.4循环

一:while循环
var i = 1
while (i<=3){
  println(i)
  i+=1
}
----------------------
1
2
3
----------------------
二:do while循环
var i = 1
do {
  println(i)
  i+=1
}while(i<=3)
----------------------
1
2
3
----------------------
三:for循环

总体的应用:for循环主要面向于集合

基本使用案例

1、range中默认增值为1

// 1 <= range <= 3
val range = 1 to 3
for (e <- range){
  println(e)
}
----------------------
1
2
3
----------------------

2、改变range中默认的增值,此处将增值改为3

val range = 1 to 10 by 3
for (e <- range){
  println(e)
}
----------------------
1
4
7
10
----------------------

3、其余计算(减,乘…),此处案例:能被3整除的数

val range = 1 to 10
for (e <- range;if (e%3==0)){
  println(e)
}
----------------------
3
6
9
----------------------
四:模式匹配(类似于switch…catch)【重点】

:基本格式

val result = someValue match {
  case 模式1 => ...  //处理模式1的情况
  case 模式2 => ...  //处理模式2的情况
  //更多模式匹配
}

【注意点】:需要提取的内容用变量,不需要提取内容用占位符(_)占位

:典型应用场景

数值

val number = Random.nextInt(4)
val rst = number match {
  case 0 => "余额"
  case 1 => "充值"
  case 2 => "活动"
  case 3 => "贷款"
  case _ => "未知"
}
println(s"$number => $rst")
------------------------
1 => 充值
------------------------

条件守卫

val age = Random.nextInt(100)
val rst = age match {
  case a if a<7 => "幼年"
  case a if a<18 => "少年"
  case a if a<30 => "青年"
  case a if a<60 => "壮年"
  case _ => "老年"
}
println(s"${age} belongs to ${rst}")
------------------------
20 belongs to 青年
------------------------

字符串+条件守卫

val content = "aa@qq.com"
val rst = content match {
  case a if a.matches("^\\w+@[0-9a-z]{2,}\\.(com|cn|org)$" ) => "邮箱"
  case a if a.matches("^1[3-9]\\d{9}$" ) => "手机号"
  case a if a.matches("^\\d{17}[0-9X]$" ) => "PID"
  case _ => "RUBBISH"
}
println(s"$content $rst")
------------------------
aa@qq.com 邮箱
------------------------

元组

val tp2 = (5,101)

//需要提取的内容用变量,不需要提取内容用占位符(_)占位
val rst = tp2 match {
  case (3,_) => (3,1)
  case (5,a) => if(a%2==0) (5,0) else (5,1)
  case _ => (0,0)
}
println(rst)
------------------------
(5,1)
------------------------

列表

val tp3:Any = List(1,"100")
val rst = tp3 match {
  case List(1,_) => "ONE"
  case List(2,_) => "TWO"
  case List(3,_) => "THREE"
  case _ => "NULL"
}
println(rst)
------------------------
ONE
------------------------

嵌套

val tp3:Any = (1,("java",67))
val rst = tp3 match {
  case (1,(sub:String,score:Int)) => (sub,score)
  case _ => ("UnknownFormat",1)
}
println(rst)
------------------------
(java,67)
------------------------

识别值的类型

val v:Any = 1
val rst = v match {
  case a:Int => f"${Math.PI*Math.pow(a,2)}%.2f"
  case a:String => "String"
  case a:Boolean => a.toString
  case _ => "unknown"
}
println(rst)
------------------------
3.14
------------------------

5、集合

必知点

1.【导包】(可变集合包 与 不可变集合包)

面向大数据时,通常使用的是不可变集合包

// immutable:不可变集合包		mutable:可变集合包
import scala.collection.immutable.Set			// 导入具体类
import scala.collection.mutable._				// 导入包内所有类
import scala.collection.mutable.{ListBuffer,ArrayBuffer}	// 导入包内部分类

注意:【默认】导入的是【不可变集合包】。

若要导入可变集合包,基本步骤如下(以导入Set为例)

1.先导入
	import scala.collection.mutable
2.再使用
	val set = mutable.Set()
2.【泛型】

=>泛型一般用中括号表示[T1,…,TN]

5.2集合的基本操作

一:分组操作(以list为例)

grouped:连续3个为一组

val list = List(1,2,3,4,5,6,7,8)
val iterator: Iterator[List[Int]] = list.grouped(3)
iterator.foreach(println)
----------------------
List(1, 2, 3)
List(4, 5, 6)
List(7, 8)
----------------------

sliding:滑动窗口=>连续3个为一组,下一组需要跳过2个数后再开始。

val list = List(1,2,3,4,5,6,7,8)
val iterator: Iterator[List[Int]] = list.sliding(3, 2)
iterator.foreach(println)
----------------------
List(1, 2, 3)
List(3, 4, 5)
List(5, 6, 7)
List(7, 8)
----------------------

combinations:以3个元素作为一个基本单位进行排列组合操作,不考虑顺序问题

val list = List(1,2,3,4)
val iterator: Iterator[List[Int]] = list.combinations(3)
iterator.foreach(println)
----------------------
List(1, 2, 3)
List(1, 2, 4)
List(1, 3, 4)
List(2, 3, 4)
----------------------

groupBy:【e的计算式子(如:e%2…)得出的值】作为,【e本身】作为

应用一:
	val list = List(1,2,3,4,5,6,7,8)
	val map: Map[Int, List[Int]] = list.groupBy(e => e % 2)
	map.foreach(println)
	----------------------
	(1,List(1, 3, 5, 7))
	(0,List(2, 4, 6, 8))
	----------------------
应用二:
	val list = List(1,2,3,4,5,6,7,8)
	val map: Map[String, List[Int]] = list.groupBy(e => if (e <= 4) "小于4" else "大于4")
	map.foreach(println)
	----------------------
	(小于4,List(1, 2, 3, 4))
	(大于4,List(5, 6, 7, 8))
	----------------------
二:交集& 并集| 差集&~(以Set为例,Set无序不重复)

【Scala支持运算符的重载】

1.交集:intersect 或 &

完整语法:

val intersect: Set[Int] = set1.intersect(set2)

简化语法:✔

val union: Set[Int] = set1 & set2

案例:

val set1 = Set(1,2,89,3,71)
val set2 = Set(1,51,2,3,17)

val intersect: Set[Int] = set1 & set2
println(intersect)
----------------------
Set(1, 2, 3)
----------------------
2.并集:union 或 |

完整语法:

val union: Set[Int] = set1.union(set2)

简化语法:✔

val union: Set[Int] = set1 | set2

案例:

val set1 = Set(1,2,89,3,71)
val set2 = Set(1,51,2,3,17)

val union: Set[Int] = set1 | set2
println(union)
----------------------
Set(89, 1, 2, 17, 71, 3, 51)
----------------------
3.差集:diff 或 &~

完整语法:

val diff: Set[Int] = set1.diff(set2)

简化语法:✔

val union: Set[Int] = set1 &~ set2

案例:

val set1 = Set(1,2,89,3,71)
val set2 = Set(1,51,2,3,17)

// set1 相对于 set2 的差集
val diff: Set[Int] = set1 &~ set2
println(diff)
----------------------
Set(89, 71)
----------------------

强调说明:差集最终的结果类型【取决于】diff左侧元素的类型。若set1为可变集合,set2为不可变集合,则set1.diff(set2)最终的结果为可变的集合。

三:集合的添加与删除操作(以Map为例)
需知知识点——图解

1.可变集合
A.声明Map集合(可变集合)
val map:mutable.Map[String,Int] = mutable.Map.empty

B.map添加操作

在一个map容器中进行添加操作

//单个添加
map += (("java",88))
//多个添加
map ++= (Array(("scala",98),("hadoop",84)))
map2.foreach(println)
----------------------
(hadoop,84)
(scala,98)
(java,88)
----------------------

C.map删除操作

//将map2容器中的 java 删除
map2 -= "java"
map2.foreach(println)
----------------------
(hadoop,84)
(scala,98)
----------------------
2.不可变集合

A.声明Map集合(不可变集合)

val map = Map.empty

B.map添加操作

在另一个map集合中保留原来内容同时进行添加操作

// 将map容器中内容 + 新添的两个内容 存放于 map2容器中
val map2: Map[String, Int] = map ++ Map(("html", 11),("java", 23))
map2.foreach(println)
----------------------
(html,11)
(java,23)
----------------------

C.map删除操作

val map4: Map[String, Int] = map2.-("html")
map4.foreach(println)
----------------------
(java,23)
----------------------

相关文章:

  • 视频提取硬字幕,字幕擦除,字幕翻译工具推荐
  • 深入理解与配置 Nginx TCP 日志输出
  • 实训任务2.2 使用Wireshark捕获数据包并分析
  • 1. 树莓派上配置机器人环境(具身智能机器人套件)
  • 启动wsl里的Ubuntu24报错:当前计算机配置不支持 WSL2,HCS_E_HYPERV_NOT_INSTALLED
  • Qt调试功能使用方法
  • 【使用hexo模板创建个人博客网站】
  • 趣味学习法,助力消防设施操作员考试
  • Spring(五)容器-依赖注入的三种方式
  • C语言——位操作运算
  • electron + vue3 + vite 主进程到渲染进程的单向通信
  • Gravitino源码分析-SparkConnector 实现原理
  • HTML5的新特性有哪些?
  • 网络安全配置截图 网络安全i
  • 【AI赋能】AI工具图文创造指南:从主题到一键发布的完整指南
  • 动态ip和静态ip适用于哪个场景?有何区别
  • CODEGEN:一种基于多轮对话的大型语言模型编程合成方法
  • 永洪科技深度分析实战,零售企业的销量预测
  • 隐私保护在 Facebook 用户身份验证中的应用
  • 从连接到交互:SDN 架构下 OpenFlow 协议的流程与报文剖析
  • 腾讯云主机能给几个网站备案/优化设计官方电子版
  • 电子商务网站建设试题答案/常州seo
  • 建设厅施工员证查询网站/优化防控措施
  • 网页跟网站的区别/企业推广宣传方式
  • 德州极速网站建设 小程序/十大网站平台
  • 上海网站设计团队/产品推广软文200字