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

Scala语法

一、Scala的数据类型

由于scala可以在Java环境中运行,所以他们的数据类型相似。例如:

Byte、Char、Short、Int、Long、Float、Double、Boolean

在Scala中各数据类型的关系如下

与Java的基本数据类型的包装类型相同,但是scala没有基本数据类型与包装类型的概念,统一都是。scala自己会负责基本数据类型和引用类型的转换操作类型的加强版类型:scala使用很多加强类给数据类型增加了上百种增强的功能或方法。

例如,Scala还提供了RichInt、RichDouble、RichChar等类型,RichInt就提供了to方法,1.to(10),此处Int先隐式转换为RichInt,然后再调用其to方法。

Any是abstract类,它是Scala类继承结构中最底层的。所有运行环境中的Scala类都是直接或间接继承自Any这个类。

AnyRef:所有引用类型的基类。

AnyVal:所有值类型的基类。

Nothing:所有类的子类,是一个类。Nothing没有对象,但是可以用来定义类型。

在cmd中运行的Scala结果

Null:所有AnyRef的子类,null是Null的唯一对象。

二、变量的定义

对比说明,在Java中,数据类型前有单独且必须的定义,这种属于强类型语言,例如

int num=10;
char ch=”a”;
Double num2=11.11;

而在Scala和JavaScript中就不需要这种强制定义,取而代之的是var和val,例如

var x=111;
var y=11.11;
var z=”hello”;val f=58;

在这里面,var定义变量;val定义常量

object VariableTest {def main(args: Array[String]) {//使用val定义的变量值是不可变的,相当于java里用final修饰的变量val i = 1//使用var定义的变量是可变的,在Scala中鼓励使用valvar s = "hello"//Scala编译器会自动推断变量的类型,必要的时候可以指定类型//变量名在前,类型在后val str: String = "world"println("i = " + i)println("s = " + s)println("str = " + str)}
}

运行结果为

i = 1
s = hello
str = worldProcess finished with exit code 0

三、基本操作符

scala的算术操作符与java的算术操作符也没什么区别,比如+、-、*、/、%等,以及&、|、^、>>、<<等。

但是,在scala中,这些操作符是数据类型的方法,比如1 + 1,可以写做1.+(1)

例如,1.to(10),又可以写做1 to 10

scala中没有提供++、--操作符,我们只能使用+和-,比如num = 1,num ++是错误的,必须写做num += 1。

四、字符串的插值操作

Scala中的三个字符串插值器:s、f、raw

s

在任何字符串前加上s,就可以直接在串中使用变量了

f

除了 s 的功能外(不指定格式就和 s 一样),还能进行格式化输出,在变量后用 % 指定输出格式

raw

除了对字面值中的字符不做编码外,raw 插值器与 s 插值器在功能上是相同的

 举栗:

1、输出“tom”的数据类型

2、引用“tom”并输出之后的数据类型

3、定义“tom”,“jim”并引用输出

五、条件表达式

  1. if
  2. if else(单分支)
  3. if else if else(多分支)
def main(args: Array[String]): Unit = {val x = 1//判断x的值,将结果赋给yval y = if (x > 0) 1 else -1//打印y的值println("y=" + y)//支持混合类型表达式val z = if (x > 1) 1 else "error"//打印z的值println("z=" + z)//如果缺失else,相当于if (x > 2) 1 else ()val m = if (x > 2) 1println("m=" + m)//在scala中每个表达式都有值,scala中有个Unit类,写做(),相当于Java中的voidval n = if (x > 2) 1 else ()println("n=" + n)
}

当y的值类型既可能为Int又可能为String时,它的类型被定义为Any,是Int和String的父类。

没有else时,会默认为else(),y的类型被定义为AnyVal

六、类型的转换

跟Java那些编程语言相同,Scala用的也是那一套

上表中列出的数据类型都是对象,也就是说scala没有java中的原生类型。在scala是可以对数字等基础类型调用方法的。

但是,Scala还是跟Java有点去别的

  1. scala中所有的类型都使用大写字母开头
  2. 整形使用 Int 而不是Integer
  3. scala中定义变量可以不写类型,让scala编译器自动推断
  4. Scala中默认的整型是Int, 默认的浮点型是: Double

scala中的类型转换分为值类型转换引用类型转换 ,  值类型转换分为:

  • 自动类型转换
  • 强制类型转换

 自动类型转换

范围小的数据类型值会自动转换为范围大的数据类型值, 这个动作就叫: 自动类型转换.
自动类型转换从小到大分别为:

Byte, Short, Char -> Int -> Long -> Float -> Double

强制类型转换

范围大的数据类型值通过一定的格式(强制转换函数)可以将其转换成范围小的数据类型值, 这个动作就叫: 强制类型转换。

但是,使用强制类型转换的时候可能会造成精度缺失问题

var name = 1

1.name.toDouble

使用toDouble、toInt等方法,对象名.to方法可以实现简单的数据类型转换。

2.name.doubleValue

可以使用doubleValue、longValue、intValue三种方法,用于简单的数据类型转换。

3.Integer.valueOf(name)

可将整型或者字符串型转换为Integer型。

4.String.valueOf(name)

可将任一类型数据转换为字符串类型(包括字符数组)

更为复杂具体的转换,需自定义转换类型及方法,使用占位符对数据集中所有元素进行指定的方式转换。

七、块表达式

先扔个栗子:

object demo01 {def main(args: Array[String]): Unit = {val x = 0val result = {if(x < 0)1else if(x >= 1)-1else"error"}println(result)}
}

在Scala中,{ }包含一系列表达式,其结果也是一个表达式。块语句中最后一个表达式的值就是块的值。

这个对于那种需要多步初始化的val的值很有用,例如:

val price = { val a = 5-c; val b=c+5;val c=3;sqrt(a*b) }

{ }块的值其最后一个表达式(粗体),a和b只是中间的计算值,很干净的部分而言不可见了。
在Scala中,赋值动作是没有值的——或者,更严谨的说:他们的值是Unit类型的。Unit类型等同于java或c++中的void,而这种类型只有一个值,写做()。

一个以赋值语句结尾的块,比如:{r= r*n; n -=n} 返回的是Unit类型的,写函数的时候要注意这一点。

由于赋值语句是Unit类型的,所以不能穿接起来,例如:x = y = 1; y=1的值是Unit ,也就是(),你肯定不会想把它赋值给x(而在java和c++中这些做法是有意义的)

八、循环语句

1、for循环

顾名思义,这里不过多解释,只通过代码表达

1、输出1到10(Scala中“-”是“=”)

2、输出1到9(包含开头不包含结尾)

3、遍历字符串(相当于java中的fore)

4、通过下标遍历字符串(length)(charAt() 方法用于返回参数中传递的索引的字符。)

 

5、遍历数组

 

6、通过下标遍历数组

 

7、双重循环

栗子:输出个位数与十位数不相同的两位数(个位、十位数均从1-3取值)

8、数组操作

对数组中的每个数乘以10,生成一个新数组

另一个方法

for 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。Scala 中 for 循环是有返回值的。如果被循环的是 Map,返回的就是Map,被循环的是 List,返回的就是 List,以此类推。

把数组中的偶数取出来乘以100得到一个新的数组

方法一(俩):

方法二(俩):

 2、while循环

while循环:基本语义与Java相同。

 3、do while循环

至少执行一次

九、操作符重载

在scala里面没有运算符,所有的符号其实都是方法。

栗子:

相当于是,1这个实例调用+方法,传入了一个参数2

定义一个 + 方法

十、方法的定义

定义一个m方法

可以不写返回值类型,会自动将方法体的最后一行作为返回值,并推导出其类型。但是递归方法一定要写返回值类型。

如果显示的指明了没有返回值,即使方法体的最后一行有返回值,也不会有值返回。

定义无参的方法(方法名  参数  返回值类型)

无返回值的三种定义方法:(第一种:正常,第二种:不写Unit,第三种:不写=)

如果方法中没有参数的话小括号是可以省略的,但是调用的时候,就不能加括号了

变长参数

在Scala中,有时我们需要将方法定义为参数个数可变的形式,则此时可以使用变长参数定义方法。

def sum(nums: Int*) = {
var res = 0
for (num <- nums)res += num
res
}
sum(1, 2, 3, 4, 5)

十一、柯里化

柯里化指的是将原来接收多个参数的方法,变成新的接收一个参数的方法。

 之前用过的fold

不传使用默认值,传值使用传了的值,传三个参数列表的情况,注意,当传入一个参数时,返回的<function1>

http://www.xdnf.cn/news/325441.html

相关文章:

  • 【Axure视频教程】中继器表格——未选、半选和全选
  • 代码随想录算法训练营第五十八天| 图论4—卡码网110. 字符串接龙,105. 有向图的完全联通
  • C# WPF 颜色拾取器
  • MySQL OCP 认证限时免费活动​ 7 月 31 日 前截止!!!
  • 多规格直线运动转换至非线性直线的转换方法
  • 【C++进阶】第1课—继承
  • C#管道通讯及传输信息丢失的原因
  • android中背压问题面试题及高质量回答范例
  • 前端面试测试题目(一)
  • 《Python星球日记》 第49天:特征工程与全流程建模
  • 认识tomcat(了解)
  • Android Studio开发安卓app 设置开机自启
  • RISC-V JTAG:开启MCU 芯片调试之旅
  • 鸿蒙知识总结
  • Promise 高频面试题
  • 证件阅读机在景区实名制应用场景的方案
  • 【数据库原理及安全实验】实验六 角色访问控制
  • 探索 C++ 语言标准演进:从 C++23 到 C++26 的飞跃
  • 轨迹预测笔记
  • 爽提“双核引擎”:驱动校园餐饮焕新升级
  • 直播数据大屏是什么?企业应如何构建直播数据大屏?
  • cursor配置mcp并使用
  • 2025-05-07-关于API Key 的安全管理办法
  • vue3+vite项目引入tailwindcss
  • ntdll!LdrpNameToOrdinal函数分析之二分查找
  • 数据可视化:php+echarts实现数据可视化
  • MySQL 中常见的日志
  • 《深度学习入门 基于Python的理论实现》思维导图
  • eclipse开发环境中缺少JavaEE组件如何安装
  • Go语言基础学习详细笔记