scala
Scala常用的转义字符(escape char)
\t 一个制表位实现对齐的功能
\n 换行符
\\ 一个\
\" 一个"
\r 一个回车 println("hello\rk");
注释(comment)
单行注释
格式 //注释文字
多行注释
格式 /* 注释文字 */
缩进和空白
使用一次tab操作实现缩进,默认整体向右边移动时候用shift+tab整体向左移
或者使用 ctrl + alt + L 来进行格式化
运算符两边习惯性各加一个空格。比如2 + 4 * 5。
一行最长不超过80个字符超过的请使用换行展示尽量保持格式优雅
格式化输出
1.//print
print(a+b)
2.//格式化输出 %是占位符
printf("名字=%s 年龄是%d 薪水%.2f 高%.3f",name,age,sal,height)
3.//$ 编译器会解析变量 ${变量} 变量里面可以运算
//scala支持使用$输出内容, 编译器会去解析$对应变量
println(s"\n个人信息如下\n 名字$name \n年龄$age \n薪水$sal ")
//如果下字符串中出现了类似${age + 10} 则表示{}是一个表达式
println(s"\n个人信息如下2\n 名字${name} \n年龄${age + 10} \n薪水${sal * 100} ")
scala变量
1.声明变量时类型可以省略编译器自动推导,即类型推导
2.类型确定后就不能修改说明Scala 是强数据类型语言.
3.//在声明/定义一个变量时可以使用var 或者 val 来修饰 var 修饰的变量可改变val 修饰的变量不可改
//val修饰的变量在编译后等同于加上final
4.var 修饰的对象引用可以改变val 修饰的则不可改变但对象的状态(值)却是可以改变的
5.变量声明时需要初始值
+的使用
当左右两边都是数值型时则做加法运算
当左右两边有一方为字符串则做拼接运算
scala数据类型
1.Scala 与 Java有着相同的数据类型在Scala中数据类型都是对象
2.Scala数据类型分为两大类
AnyVal(值类型)
AnyRef(引用类型)
注意不管是AnyVal还是AnyRef 都是对象。
数据类型列表
数据类型 |
描述 |
---|
Byte |
8位有符号补码整数。数值区间为 -128 到 127 |
Short |
16位有符号补码整数。数值区间为 -32768 到 32767 |
Int |
32位有符号补码整数。数值区间为 -2147483648 到 2147483647 |
Long |
64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 |
Float |
32 位, IEEE 754标准的单精度浮点数 |
Double |
64 位 IEEE 754标准的双精度浮点数 |
Char |
16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF |
String |
字符序列 |
Boolean |
true或false |
Unit |
表示无值和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值写成()。 |
Null |
null |
Nothing |
Nothing类型在Scala的类层级的最低端它是任何其他类型的子类型。 |
Any |
Any是所有其他类的超类 |
AnyRef |
AnyRef类是Scala里所有引用类(reference class)的基类 |
整数类型
1.Scala各整数类型有固定的表数范围和字段长度不受具体OS的影响以保证Scala程序的可移植性
2.Scala的整型 常量/字面量 默认为 Int 型声明Long型 常量/字面量 须后加‘l’’或‘L’
3.Scala程序中变量常声明为Int型除非不足以表示大数才使用Long
浮点类型
Float [4] |
32 位, IEEE 754标准的单精度浮点数 |
---|
Double [8] |
64 位 IEEE 754标准的双精度浮点数 |
Scala的浮点类型可以表示一个小数比如 123.4f7.8 0.12等等
1.与整数类型类似Scala 浮点类型也有固定的表数范围和字段长度不受具体OS的影响。
2.Scala的浮点型常量默认为Double型声明Float型常量须后加‘f’或‘F’。
3.浮点型常量有两种表示形式
十进制数形式如5.12 512.0f .512 (必须有小数点
科学计数法形式:如5.12e2 = 5.12乘以10的2次方 5.12E-2 = 5.12除以10的2次方
4.通常情况下应该使用Double型因为它比Float型更精确(小数点后大致7位)
//测试数据 2.2345678912f , 2.2345678912 float回精度丢失
字符类型
布尔类型
布尔类型也叫Boolean类型Booolean类型数据只允许取值true和falseboolean类型占1个字节。
boolean一般用于
if条件控制语句
while循环控制语句
do-while循环控制语句
for循环控制语句
Unit类型、Null类型和Nothing类型
Unit |
表示无值和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值写成()。 |
---|
Null |
null , Null 类型只有一个实例值 null |
Nothing |
Nothing类型在Scala的类层级的最低端它是任何其他类型的子类型。当一个函数我们确定没有正常的返回值可以用Nothing 来指定返回类型这样有一个好处就是我们可以把返回的值异常赋给其它的函数或者变量兼容性 |
值类型转换
当Scala程序在进行赋值或者运算时精度小的类型自动转换为精度大的数据类型这个就是自动类型转换(隐式转换)
值类型隐式转换
1.有多种类型的数据混合运算时系统首先自动将所有数据转换成容量最大的那种数据类型然后再进行计算。
5.6 + 10 = 》double
2.当我们把精度(容量)大 的数据类型赋值给精度(容量)小 的数据类型时就会报错反之就会进行自动类型转换。
(byte, short) 和 char之间不会相互自动转换。
3.byteshortchar 他们三者可以计算在计算时首先转换为int类型。
4.自动提升原则 表达式结果的类型自动提升为 操作数中最大的类型
强制类型转换
自动类型转换的逆过程将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转函数但可能造成精度降低或溢出
1.当进行数据的 从 大——>小就需要使用到强制转换
2.强转符号只针对于最近的操作数有效往往会使用小括号提升优先级
3.Char类型可以保存 Int的常量值但不能保存Int的变量值需要强转
val num1: Int = 10 * 3.5.toInt + 6 * 1.5.toInt // 36
val num2: Int = (10 * 3.5 + 6 * 1.5).toInt // 44
println(num1 + " " + num2)
4.Byte和Short类型在进行运算时当做Int类型处理。
值类型和String类型的转换
1.值类型和String类型的转换
语法 将基本类型的值+"" 即可
String s1 = 4.5 + ""
2.String类型转基本数据类型
语法通过基本类型的String的 toXxx方法即可
s1.toInt
s1.toFloat
s1.toDouble
s1.toByte
s1.toLong
s1.toShort
标识符的命名规范
Scala中的标识符声明基本和Java是一致的但是细节上会有所变化。
首字符为字母后续字符任意字母和数字美元符号可后接下划线_
数字不可以开头。
//首字符为操作符(比如+ - * / )后续字符也需跟操作符 ,至少一个(反编译)
var ++ = 90
操作符(比如+-*/)不能在标识符中间和最后.
var a-b = 88 错了
用反引号`....`包括的任意字符串即使是关键字(39个)也可以 [true]
var 'true' = 11
标识符命名注意事项
包名尽量采取有意义的包名简短有意义
变量名、函数名 、方法名 采用驼峰法
scala关键字
package, import, class, object, trait, extends, with, type, forSome
private, protected, abstract, sealed, final, implicit, lazy, override
try, catch, finally, throw
if, else, match, case, do, while, for, return, yield
def, val, var
this, super
new
true, false, null
运算符
算术运算符
运算符 |
运算 |
范例 |
结果 |
---|
+ |
正号 |
+3 |
3 |
- |
负号 |
b=4; -b |
-4 |
+ |
加 |
5+5 |
10 |
- |
减 |
6-4 |
2 |
* |
乘 |
3*4 |
12 |
/ |
除 |
5/5 |
1 |
% |
取模(取余) |
7%5 |
2 |
+ |
字符串相加 |
“He”+”llo” |
“Hello” |
num++ = num += 1
num-- = num -= 1
假如还有97天放假问xx个星期零xx天
val days = 97
printf("统计结果是 %d个星期零%d天", days / 7, days % 7)
//%是占位符后面变量会为前面赋值 val值不能改变 var能改变
println :
printf:
print:
Print :print--是函数可以返回一个值只能有一个参数
Println :可以打印出字符串和变量 ,println与print唯一的区别是println换行输出。
Printf : 只可以打印出格式化的字符串,可以输出字符串类型的变量不可以输出整形变量和整形
关系运算符(比较运算符)
关系运算符的结果都是boolean型也就是要么是true要么是false
关系表达式 经常用在 if结构的条件中或循环结构的条件中
//细节
关系运算符的结果都是Boolean型也就是要么是true要么是false。
关系运算符组成的表达式我们称为关系表达式。 a > b
比较运算符“==”不能误写成“=”
使用陷阱: 如果两个浮点数进行比较应当保证数据类型一致.
运算符 |
运算 范例 结果 |
---|
== |
相等于 4==3 false |
!= |
不等于 4!=3 true |
< |
小于 4<3 false |
> |
大于 4>3 true |
<= |
小于等于 4<=3 false |
>= |
大于等于 4>=3 true |
逻辑运算符
&& false
|| true
运算符 |
描述 |
实例 |
---|
&& |
逻辑与 |
(A && B) 运算结果为 false |
|| |
逻辑或 |
(A || B) 运算结果为 true |
! |
逻辑非 |
!(A && B) 运算结果为 true |
赋值运算符
var num = 2
num <<= 2 // num = 8 相当于2*2*2
num >>= 1 // num = 4 相当于8/2
println("num=" + num)
运算符 |
描述 |
实例 |
---|
<<= |
左移后赋值 |
C <<= 2 等于 C = C << 2 |
>>= |
右移后赋值 |
C >>= 2 等于 C = C >> 2 |
&= |
按位与后赋值 |
C &= 2 等于 C = C & 2 |
^= |
按位异或后赋值 |
C ^= 2 等于 C = C ^ 2 |
|= |
按位或后赋值 |
C |= 2 等于 C = C | 2 |
位运算符
Scala不支持三目运算符 , 在Scala 中使用 if – else 的方式实现。
val num = 5 > 4 ? 5 : 4 //没有
val num = if (5>4) 5 else 4 //正确的
如果指定 A = 60; 及 B = 13; 两个变量对应的二进制为
A = 0011 1100
B = 0000 1101
-------位运算----------
A&B = 0000 1100 // 12
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
运算符 |
描述 |
实例 |
---|
& |
按位与运算符 |
(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 |
运算符优先级
1) 运算符有不同的优先级所谓优先级就是表达式运算中的运算顺序。如右表上一行运算符总优先于下一行。
2) 只有单目运算符、赋值运算符是从右向左运算的。
3) 运算符的优先级和Java一样。
小结运算符的优先级
1.() []
2.单目运算
3.算术运算符
4.移位运算
5.比较运算符(关系运算符)
6.位运算
7.关系运算符
8.赋值运算
9.,
类别 |
运算符 |
关联性 |
---|
1 |
() [] |
左到右 |
2 |
! ~ |
右到左 |
3 |
* / % |
左到右 |
4 |
+ - |
左到右 |
5 |
>> >>> << |
左到右 |
6 |
> >= < <= |
左到右 |
7 |
== != |
左到右 |
8 |
& |
左到右 |
9 |
^ |
左到右 |
10 |
| |
左到右 |
11 |
&& |
左到右 |
12 |
|| |
左到右 |
13 |
= += -= *= /= %= >>= <<= &= ^= |= |
右到左 |
14 |
, |
左到右 |
键盘输入语句
在编程中需要接收用户输入的数据就可以使用键盘输入语句来获取。InputDemo.scala
步骤
导入该类的所在包
创建该类对象声明变量
调用里面的功能
案例演示
要求可以从控制台接收用户信息【姓名年龄薪水】。
回顾Java的实现//不说明
Scala的实现 【 import scala.io.StdIn】
StdIn.readLine() //控制台输入
//
println("请输入xxx")
val score = Stdin.readDouble()
程序流程控制介绍
顺序控制
分支控制
循环控制
顺序控制
程序从上到下逐行地执行中间没有任何判断和跳转
分支控制if-else
单分支
基本语法
if (条件表达式) {
执行代码块
}
说明当条件表达式为ture 时就会执行 { } 的代码。
双分支
基本语法
if (条件表达式) {
执行代码块1
} else {
执行代码块2
}
说明当条件表达式成立即执行代码块1否则执行代码块2.
分支控制注意事项
如果大括号{}内的逻辑代码只有一行大括号可以省略, 这点和java 的规定一样。
Scala中任意表达式都是有返回值的也就意味着if else表达式其实是有返回结果的具体返回结果的值取决于满足条件的代码体的最后一行内容.[案例演示]
Scala中是没有三元运算符因为可以这样简写
// Scala
val result = if (flg) 1 else 0
嵌套分支
在一个分支结构中又完整的嵌套了另一个完整的分支结构里面的分支的结构称为内层分支外面的分支结构称为外层分支。嵌套分支不要超过3层
基本语法
if(){
if(){
}else{
}
}
switch分支结构
在scala中没有switch,而是使用模式匹配来处理。
模式匹配涉及到的知识点较为综合因此我们放在后面讲解。
match-case
for循环控制
基本案例
for(i <- 1 to 3) {
print(i + " ")
}
println()
说明:
这种方式和前面的区别在于 i 是从1 到 3-1
前闭合后开的范围,和java的arr.length() 类似
范围数据循环方式1
//
for (int i = 0; i < arr.lenght; i++){}
def main(args: Array[String]): Unit = {
//输出10句 "hello,尚硅谷!"
val start = 1
val end = 10
//说明
//1. start 从哪个数开始循环
//2. to 是关键字
//3. end 循环结束的值
//4. start to end 表示前后闭合
for (i <- start to end) {
println("你好 nnn" + i)
}
//说明for 这种推导时也可以直接对集合进行遍历
var list = List("hello", 10, 30, "tom")
for (item <- list) {
println("item=" + item)
}
范围数据循环方式2
def main(args: Array[String]): Unit = {
//输出10句 "hello"
val start = 1
val end = 11
//循环的范围是 start --- (end-1)
for (i <- start until end) {
println("hello" + i)
}
}
//until 不包含最后一位
//to 包含最后一位
说明:
until这种方式和前面的区别在于 i 是从1 到 3-1
前闭合后开的范围,和java的arr.length() 类似
for (int i = 0; i < arr.lenght; i++){}
输出10句 "hello"
循环守卫
基本案例
for(i <- 1 to 3 if i != 2) { //输出结果为 1 3如果i=2就跳过
print(i + " ")
}
基本案例说明
循环守卫即循环保护式也称条件判断式守卫。保护式为true则进入循环体内部为false则跳过类似于continue
//上面的代码等价
for (i <- 1 to 3) {
if (i != 2) {
println(i+"")
}
}
引入变量
基本案例
for(i <- 1 to 3; j = 4 - i) { //把方法体里面的数据放到for循环里面
print(j + " ")
}
对基本案例说明
没有关键字所以范围后一定要加来隔断逻辑
上面的代码等价
for ( i <- 1 to 3) {
val j = 4 –i
print(j+"")
}
嵌套循环
基本案例
for(i <- 1 to 3; j <- 1 to 3) {
println(" i =" + i + " j = " + j)
}
对基本案例说明
没有关键字所以范围后一定要加来隔断逻辑
上面的代码等价
for ( i <- 1 to 3) {
for ( j <- 1 to 3){
println(i + " " + j + " ")
}
}
循环返回值
//将遍历过程中处理的结果返回到一个新Vector集合中使用yield关键字
def main(args: Array[String]): Unit = {
//说明 val res = for(i <- 1 to 10) yield i 含义
//1. 对1 to 10 进行遍历
//2. yield i 将每次循环得到i 放入到集合Vector中并返回给res
//3. i 这里是一个代码块这就意味我们可以对i进行处理
//4. 下面的这个方式就体现出scala一个重要的语法特点就是将一个集合中个各个数据
// 进行处理并返回给新的集合
val res = for(i <- 1 to 10) yield {
if (i % 2 == 0) {
i
}else {
"不是偶数"
}
}
println(res)
}
使用花括号{}代替小括号()
基本案例
for(i <- 1 to 3; j = i * 2) {
println(" i= " + i + " j= " + j)
}
可以写成
for{
i <- 1 to 3
j = i * 2} {
println(" i= " + i + " j= " + j)
}
//对基本案例说明
{}和()对于for表达式来说都可以
for 推导式有一个不成文的约定
当for 推导式仅包含单一表达式时使用圆括号
当其包含多个表达式时使用大括号
当使用{} 来换行写表达式时分号就不用写了
scala 的步长控制
scala 的for循环的步长如何控制! [for(i <- Range(1,3,2)]
//步长控制为2
//Range(1,10,2)的对应的构建方法是
//def apply(start: Int, end: Int, step: Int): Range = new Range(start, end, step)
for (i <- Range(1, 10, 2)) { //输出结果为 1 3 5 7 9 // 1开始 10结束 2隔2输出一次
println("i=" + i)
}
while循环控制
基本语法
循环变量初始化
while (循环条件) {
循环体(语句)
循环变量迭代
}
def main(args: Array[String]): Unit = {
//输出10句 hello
//1. 定义循环变量
var i = 0
//2. i < 10 条件
while (i < 10){
println("hello" + i) //循环体
//循环变量迭代
i += 1
}
}
//注意事项
1.循环条件是返回一个布尔值的表达式
2.while循环是先判断再执行语句
3.与If语句不同While语句本身没有值即整个While语句的结果是Unit类型的()
4.因为while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量,而变量需要声明在 while循环的外部那么就等同于循环的内部对外部的变量造成了影响所以不推荐使用而是推荐使用for循环。
do..while循环控制
//基本语法
循环变量初始化;
do{
循环体(语句)
循环变量迭代
} while(循环条件)
//例子
def main(args: Array[String]): Unit = {
var i = 0 // for
do {
printf(i + "hello" )
i += 1
} while (i < 10)
}
//注意事项
1.循环条件是返回一个布尔值的表达式
2.do..while循环是先执行再判断
3.和while 一样因为do…while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量 而 变量需要声明在do...while循环的外部那么就等同于循环的内部对外部的变量造成了影响所以不推荐使用而 是推荐使用for循环
多重循环控制
1.将一个循环放在另一个循环体内就形成了嵌套循环。其中for ,while ,do…while均可以作为外层循环和内层循环。【建议一般使用两层最多不要超过3层】
2.实质上嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时才会完全跳出内层循环才可结束外层的当次循环开始下一次的循环。
3.设外层循环次数为m次内层为n次 则内层循环体实际上需要执行m*n=mn次。
while循环的中断
break
//break:
import util.control.Breaks._
object WhileBreak {
def main(args: Array[String]): Unit = {
var n = 1
//breakable()函数
//说明
//1. breakable 是一个高阶函数可以接收函数的函数就是高阶函数
//2. def breakable(op: => Unit) {
// try {
// op
// } catch {
// case ex: BreakControl =>
// if (ex ne breakException) throw ex
// }
// }
// (1) op: => Unit 表示接收的参数是一个没有输入也没有返回值的函数
// (2) 即可以简单理解可以接收一段代码块
// 3. breakable 对break()抛出的异常做了处理,代码就继续执行
// 4. 当我们传入的是代码块scala程序员会将() 改成{}
breakable {
while (n <= 20) {
n += 1
println("n=" + n)
if (n == 18) {
//中断while
//说明
//1. 在scala中使用函数式的break函数中断循环
//2. def break(): Nothing = { throw breakException }
break()
}
}
}
continue
//continue结束本次符合条件的循环循环会继续执行
//break 结束所有的循环直接跳出循环体
Scala内置控制结构特地也去掉了continue是为了更好的适应函数化编程可以使用if – else 或是 循环守卫实现continue的效果
object ContinueDemo {
def main(args: Array[String]): Unit = {
//说明
//1. 1 to 10
//2. 循环守卫 if (i != 2 && i != 3) 这个条件为ture,才执行循环体
// 即当i ==2 或者 i == 3时就跳过
for (i <- 1 to 10 if (i != 2 && i != 3)) {
println("i=" + i)
}
//也可以写成如下的形式
println("============================")
for (i <- 1 to 10) {
if (i != 2 && i != 3){
println("i=" + i)
}
}
}
}