Scala学习笔记

累了,基础配置不想写了,直接抄了→Scala的环境搭建

这里需要注意的是,创建新项目时,不要用默认的Class类,用Object,原因看→scala中的object为什么可以直接运行

一、Scala简介

1.1 图解Scala和Java的关系

1.2 关键字说明

package: 包,等同于java中的package

object:关键字,声明一个单例对象(伴生对象)

main方法:从外部可以直接调用执行的方法

def 方法名称 ( 参数名称 : 参数类型 ) : 返回值类型 = { 方法体 }

Scala 完全面向对象,故scala去掉了Java中非面向对象的元素,如static关键字,void类型
1) static
scala无static关键字,由object实现类似静态方法的功能(类名.方法名)
class关键字和Java中的class关键字作用相同,用来定义一个类
2) void
对于无返回值的函数,scala定义其返回值类型为Unit类型

1.3 代码案例


     
     
  1. package com.scala.chapter1
  2. object Hello {
  3. def main (args: Array[String]): Unit = {
  4. println( "hello scala")
  5. System.out.println( "hello scala")
  6. }
  7. }

1.4 Scala语言特点

Scala是一门以Java虚拟机 (JVM)为运行环境并将面向对象函数式编程的最佳特性结合在一起的静态类型编程语言(静态语言需要提前编译的如: Java、C、C++等,动态语言如:JS)。

1)Scala是一门多范式的编程语言,Scala支持面向对象和函数式编程。 (多范式,就是多种编程方法的意思。有面向过程、面向对象、泛型、函数式四种程序设计方法。)

2)Scala源代码 (.scala) 会被编译成Java字节码 (.class),然后运行于JVM之上,并可以调用现有的Java类库实现两种语言的无缝对接

3)Scala单作为一门语言来看,非常的简洁高效

4)Scala在设计时,马丁·奥德斯基是参考了Java的设计思想,可以说Scala是源于Java,同时马丁·奥德斯基也加入了自己的思想,将函数式编程语言的特点融合到JAVA中,因此,对于学习过Java的同学,只要在学习Scala的过程中,搞清楚Scala和Java相同点和不同点,就可以快速的掌握Scala这门语言。

二、变量和数据类型

Any: 所有类型的超类(顶级类型)
AnyVal: 值类型的超类
AnyRef: 引用类型的超类,对应java.lang.Object
Unit: 无值,类似java中的void
Nothing: 所有类型的子类
Null: 表示null或空引用

2.1 注释

Scala注释使用和Java完全一样。

注释是一个程序员必须要具有的良好编程习惯。将自己的思想通过注释先整理出来,再用代码去体现。

1)基本语法


     
     
  1. 1)单行注释: //
  2. 2)多行注释: /* */
  3. 3)文档注释: /**
  4. *
  5. */

2)案例实操


     
     
  1. object Test1 {
  2. def main(args: Array[ String]): Unit = {
  3. //单行注释
  4. println( "单行")
  5. //多行
  6. /*
  7. println("多行")
  8. */
  9. //文档注释
  10. /**
  11. * println("文档注释")
  12. */
  13. }
  14. }

3) 代码规范

(1)使用一次tab操作,实现缩进,默认整体向右边移动,用shift+tab整体向左移

(2)或者使用ctrl + alt + L来进行格式化

(3)运算符两边习惯性各加一个空格。比如:2 + 4 * 5

(4)一行最长不超过80个字符,超过的请使用换行展示,尽量保持格式优雅

2.2 变量和常量(重点)

常量:在程序执行的过程中,其值不会被改变的变量

1)基本语法

var 变量名 [: 变量类型] = 初始值 var i:Int = 10

val 常量名 [: 常量类型] = 初始值 val j:Int = 20

注意:能用常量的地方不用变量

2)案例实操

(1)声明变量时,类型可以省略,编译器自动推导,即类型推导

(2)类型确定后,就不能修改,说明Scala是强数据类型语言。

(3)变量声明时,必须要有初始值

(4)在声明/定义一个变量时,可以使用var或者val来修饰,var修饰的变量可改变,val修饰的变量不可改。


     
     
  1. object TestValueTransfer {
  2. def main(args: Array[ String]): Unit = {
  3. var n = 1 + 2.2222
  4. println(n) //Double
  5. var n2: Double = 2.2222
  6. // var n3: Int = n2 //报错
  7. var n4 : Byte = 44
  8. // var c1 : Char = n4 //报错
  9. var n5 : Int = n4
  10. var n6 : Byte = 66
  11. var c2 : Char = 22
  12. // var n : Short = n6 + c2 //报错,结果是Int类型
  13. // var n7 : Short = 10 + 20 //报错,byte,short,char他们三者可以计算,在计算时首先转换为int类型。
  14. }
  15. }

(5)var修饰的对象引用可以改变,val修饰的对象则不可改变,但对象的状态(值)却是可以改变的。(比如:自定义对象、数组、集合等等)


     
     
  1. object TestVar {
  2. def main(args: Array[ String]): Unit = {
  3. var age = 22
  4. age = 29
  5. // age = "hh" //报错
  6. var n1 = 1 //可变
  7. n1 = 2
  8. val n2 = 2 //不可变
  9. //n2 = 3
  10. //p1 是var修饰的,p1的属性可以变,p1本身也可以变
  11. var p1 = new Person()
  12. p1.name = "varp1"
  13. p1 = null
  14. val p2 = new Person()
  15. p2.name = "valp2"
  16. // p2 = null //报错
  17. }
  18. class Person {
  19. var name: String = "who"
  20. }
  21. }

2.3 标识符的命名规范

Scala对各种变量、方法、函数等命名时使用的字符序列称为标识符。即:凡是自己可以起名字的地方都叫标识符。

1)命名规则

Scala中的标识符声明,基本和Java是一致的,但是细节上会有所变化,有以下三种规则:

(1)以字母或者下划线开头,后接字母、数字、下划线

(2)以操作符开头,且只包含操作符(+ - * / # !等)

(3)用反引号....包括的任意字符串,即使是Scala关键字(39个)也可以


     
     
  1. package, import, class, object, trait, extends, with, type, for
  2. private, protected, abstract, sealed, final, implicit, lazy, override
  3. try, catch, finally, throw
  4. if, else, match, case, do, while, for, return, yield
  5. def, val, var
  6. this, super
  7. new
  8. true, false, null

2)案例实操

需求:判断hello、Hello12、1hello、h-b、x h、h_4、ab、Int、、+-/#!、+-/#!1、if、if,这些名字是否合法。


     
     
  1. object TestName {
  2. def main(args: Array[ String]): Unit = {
  3. //1.以字母或者下划线开头,后接字母、数字、下划线
  4. var hello: String = ""
  5. var hello2: String = " "
  6. // var 1 hello:String = "" 数字不能开头
  7. // var h - b: String = "" 不能用-
  8. // var x h: String = "" 不能用空格
  9. var h_4: String = ""
  10. val _ab: String = ""
  11. var Int: String = "" //ok 因为在Scala中Int是预定义的字符,不是关键字,但不推荐
  12. var _: String = "" // ok 单独一个下划线不可以作为标识符,因为_被认为是一个方法
  13. //2.以操作符开头,且只包含操作符(+ - * / # ! 等)
  14. var +*-/#! : String = ""
  15. // var +*-/#!1 : String = "" 以操作符开头必须都是操作符
  16. //3.用反引号`...`包括的任意字符串,即使是Scala关键字(39)个也可以
  17. // var if:String = "" 不用用关键字
  18. var ` if`: String = ""
  19. }
  20. }

2.4 字符串输出

1)基本语法

(1)字符串,通过+号连接

(2)printf用法:字符串,通过%传值。

(3)字符串模板(插值字符串):通过$获取变量值

2)案例实操


     
     
  1. object TestCharType {
  2. def main(args: Array[ String]): Unit = {
  3. var name: String = "zhangsan"
  4. var age: Int = 22
  5. //1.字符串 通过 + 号连接
  6. println(name + " " + age)
  7. //2.printf 用法字符串,通过%传值
  8. printf( "name=%s age=%d\n", name, age)
  9. //3.字符串,通过$引用
  10. //多行字符串,在Scala中,利用三个双引号包围多行字符串就可以实现。//输入的内容,带有空格、\t之类,导致每一行的开始位置不能整洁对齐。
  11. //应用scala的stripMargin方法,在scala中stripMargin默认是“|”作为连接符,//在多行换行的行头前面加一个“|”符号即可。
  12. val s =
  13. """
  14. | select
  15. | name
  16. |,
  17. |age
  18. |from user
  19. |where name = "zhangsan"
  20. """.stripMargin
  21. println(s)
  22. //如果需要对变量进行运算,那么可以加${}
  23. val s1 =
  24. s"" "
  25. | select
  26. | name
  27. |,
  28. |age
  29. |from user
  30. |where name="$ name" and age=${age + 2}
  31. " "".stripMargin
  32. val s2 = s"name=$name"
  33. println(s2)
  34. }
  35. }

2.5 键盘输入

在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。

1)基本语法

StdIn.readLine()、StdIn.readShort()、StdIn.readDouble()

2)案例实操

需求:可以从控制台接收用户信息,【姓名,年龄,薪水】。


     
     
  1. import scala.io. StdIn
  2. object TestInput {
  3. def main(args: Array[ String]): Unit = {
  4. // 输入姓名
  5. println( "input name:")
  6. var name = StdIn.readLine()
  7. // 输入年龄
  8. println( "input age:")
  9. var age = StdIn.readShort()
  10. // 输入薪水
  11. println( "input sal:")
  12. var sal = StdIn.readDouble()
  13. // 打印
  14. println( "name=" + name)
  15. println( "age=" + age)
  16. println( "sal=" + sal)
  17. }
  18. }

从文件中读取数据:


     
     
  1. import scala.io. Source;
  2. Source.fromFile( "C:\\Users\\90513\\Desktop\\datas.csv").foreach(print)

2.6 数据类型(重点)

  • Java 数据类型

Java基本数据类型:char、byte、short、int、long、float、double、boolean

Java引用类型:(对象类型)

由于Java有基本类型,而且基本类型不是真正意义的对象,即使后面产生了基本类型的包装类,但是仍然存在基本数据类型,所以Java语言并不是真正意义上的面向对象

Java基本类型的包装类:Character、Byte、Short、Integer、Long、Float、Double、Boolean

注意:Java中基本类型和引用类型没有共同的祖先

  • Scala 数据类型

2.7 整数类型(Byte、Short、Int、Long)

Scala的整数类型就是用于存放整数值的,比如12,30,3456等等。

1)整型分类

数据类型

描述

Byte [1]

8位有符号补码整数。数值区间为 -128 到 127

Short [2]

16位有符号补码整数。数值区间为 -32768 到 32767

Int [4]

32位有符号补码整数。数值区间为 -2147483648 到 2147483647

Long [8]

64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 = 2的(64-1)次方-1

2)案例实操

(1)Scala各整数类型有固定的表示范围和字段长度,不受具体操作的影响,以保证Scala程序的可移植性。

(2)Scala的整型,默认为Int型,声明Long型,须后加‘l’或‘L’


     
     
  1. object TestDataType {
  2. def main (args: Array[String]): Unit = {
  3. // 正确
  4. var n1: Byte = 127
  5. var n2: Byte = - 128
  6. // 错误
  7. // var n3:Byte = 128
  8. // var n4:Byte = -129
  9. // Scala的整型,默认为Int型,声明Long型,然后加”i“ 或者 ”L“
  10. var n5 = 10
  11. println(n5)
  12. var n6 = 98989898989898989L
  13. println(n6)
  14. var n7 = 2.43434309898f
  15. var n8 = 2.4343662343223
  16. println(n7)
  17. println(n8)
  18. var God = new God()
  19. God = null
  20. //var n1 : Int = null //错误
  21. //println("n1:" + n1)
  22. }
  23. class God {
  24. }
  25. }

(3)Scala程序中变量常声明为Int型,除非不足以表示大数,才使用Long

2.8 浮点类型(Float、Double)

Scala的浮点类型可以表示一个小数,比如123.4f,7.8,0.12等等。

1)浮点型分类

数据类型

描述

Float [4]

32 位, IEEE 754标准的单精度浮点数

Double [8]

64 位 IEEE 754标准的双精度浮点数

2)案例实操

Scala的浮点型常量默认为Double型,声明Float型常量,须后加‘f’或‘F’。


     
     
  1. object TestDataType {
  2. def main (args: Array[String]): Unit = {
  3. // 正确
  4. var n1: Byte = 127
  5. var n2: Byte = - 128
  6. // 错误
  7. // var n3:Byte = 128
  8. // var n4:Byte = -129
  9. // Scala的整型,默认为Int型,声明Long型,然后加”i“ 或者 ”L“
  10. var n5 = 10
  11. println(n5)
  12. var n6 = 98989898989898989L
  13. println(n6)
  14. var n7 = 2.43434309898f
  15. var n8 = 2.4343662343223
  16. println(n7)
  17. println(n8)
  18. var God = new God()
  19. God = null
  20. //var n1 : Int = null //错误
  21. //println("n1:" + n1)
  22. }
  23. class God {
  24. }
  25. }

2.9 字符类型(Char)

1)基本说明

字符类型可以表示单个字符,字符类型是Char。

2)案例实操

(1)字符常量是用单引号 ’ ’ 括起来的单个字符。

(2)\t :一个制表位,实现对齐的功能

(3)\n :换行符

(4)\\ :表示\

(5)" :表示"


     
     
  1. package com.atguigu.chapter1
  2. object TestCharType2 {
  3. def main (args: Array[String]): Unit = {
  4. var c1: Char = 'a'
  5. println( "c1=" + c1)
  6. //注意:这里涉及自动类型提升,其实编译器可以自定判断是否超出范围
  7. //不过idea提示报错
  8. var c2: Char = 'a' + 1
  9. println(c2)
  10. // \t :一个制表位,实现对齐的功能
  11. println( "姓名\t年龄")
  12. // \n :换行符
  13. println( "西门庆\n潘金莲")
  14. //(4)\\ :表示\
  15. println( "c:\\天黑了\\饿狼来了")
  16. //(5)\" :表示"
  17. println( "你过来:\"看我一拳打死你\"")
  18. }
  19. }

2.10 布尔类型:Boolean

1)基本说明

(1)布尔类型也叫Boolean类型,Booolean类型数据只允许取值true和false

(2)boolean类型占1个字节。

2)案例实操


     
     
  1. object TestBooleanType {
  2. def main (args: Array[String]): Unit = {
  3. var isResult : Boolean = false
  4. var isResult2 : Boolean = true
  5. }
  6. }

2.11 Unit类型、Null类型和Nothing类型(重点)

1)基本说明

数据类型

描述

Unit

表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。

Null

null , Null 类型只有一个实例值null

Nothing

Nothing类型在Scala的类层级最低端;它是任何其他类型的子类型。 当一个函数,我们确定没有正常的返回值(如抛出异常),可以用Nothing来指定返回类型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它的函数或者变量(兼容性

在Java中有时候有返回值,如int,但有些情况下会抛出异常。为了兼容多种可能性,就可以使用nothing类型。

2)案例实操

(1)Unit类型用来标识过程,也就是没有明确返回值的函数。

由此可见,Unit类似于Java里的void。Unit只有一个实例——( ),这个实例也没有实质意义


     
     
  1. def m1(): Unit={
  2.     println( "m1被执行")
  3. }
  4. val a: Unit=m1()
  5. println( "a="+a)
  6. // 输出:a=()

(2)Null类只有一个实例对象,Null类似于Java中的null引用。Null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal)


     
     
  1. object TestDataType {
  2. def main(args: Array[ String]): Unit = {
  3. // 正确
  4. var n1: Byte = 127
  5. var n2: Byte = -128
  6. // 错误
  7. // var n3:Byte = 128
  8. // var n4:Byte = -129
  9. // Scala的整型,默认为Int型,声明Long型,然后加”i“ 或者 ”L“
  10. var n5 = 10
  11. println(n5)
  12. var n6 = 98989898989898989L
  13. println(n6)
  14. var n7 = 2.43434309898f
  15. var n8 = 2.4343662343223
  16. println(n7)
  17. println(n8)
  18. // null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal)
  19. var God = new God()
  20. God = null
  21. // var n1: Int = null //错误
  22. // println("n1:" + n1)
  23. }
  24. class God {
  25. }
  26. }

(3)Nothing,可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容。


     
     
  1. object TestSpecialType {
  2. def test(): Nothing = {
  3. throw new Exception
  4. }
  5. test()
  6. }
  7. }

2.12 类型转换

2.12.1 数值类型自动转换

当Scala程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数值类型,这个就是自动类型转换(隐式转换)。数据类型按精度(容量)大小排序为:

1)基本说明

(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算。

(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。

(3)(byte,short)和char之间不会相互自动转换。

(4)byte,short,char他们三者可以计算,在计算时首先转换为int类型。

2)案例实操


     
     
  1. object TestValueTransfer {
  2. def main(args: Array[ String]): Unit = {
  3. //(1)自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数值类型,然后再进行计算。
  4. var n = 1 + 2.2222
  5. println(n) //Double
  6. //(2)把精度大的数值类型赋值给精度小的数值类型时,就会报错,反之就会进行自动类型转换。
  7. var n2: Double = 2.2222
  8. // var n3: Int = n2 //报错
  9. //(3)(byte,short)和char之间不会相互自动转换。
  10. var n4: Byte = 44
  11. // var c1 : Char = n4 //报错
  12. var n5: Int = n4
  13. //(4)byte,short,char他们三者可以计算,在计算时首先转换为int类型。
  14. var n6: Byte = 66
  15. var c2: Char = 22
  16. // var n : Short = n6 + c2 //报错,结果是Int类型
  17. // var n7 : Short = 10 + 20 //报错,byte,short,char他们三者可以计算,在计算时首先转换为int类型。
  18. }
  19. }

注意:Scala还提供了非常强大的隐式转换机制(隐式函数,隐式类等),我们放在高级部分专门用一个章节来讲解。

2.12.2 强制类型转换

1)基本说明

自动类型转换的逆过程,将精度大的数值类型转换为精度小的数值类型。使用时要加上强制转函数,但可能造成精度降低或溢出,格外要注意。

2)案例实操

(1)将数据由高精度转换为低精度,就需要使用到强制转换

(2)强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级


     
     
  1. object TestForceTransfer {
  2. def main(args: Array[ String]): Unit = {
  3. //(1)将数据由高精度转换为低精度,就需要使用到强制转换
  4. var n1: Int = 2.5.toInt // 这个存在精度损失
  5. //(2)强转符号只针对于最近的操作数有效,往往会使用小括号提升优先级
  6. var r1: Int = 10 * 3.5.toInt + 6 * 1.5.toInt // 10 *3 + 6*1 = 36
  7. var r2: Int = ( 10 * 3.5 + 6 * 1.5).toInt // 44.0.toInt = 44
  8. println( "r1=" + r1 + " r2=" + r2)
  9. }
  10. }

2.12.3 数值类型和String类型间转换

1)基本说明

在程序开发中,我们经常需要将基本数值类型转成String类型。或者将String类型转成基本数值类型。

2)案例实操

(1)基本类型转String类型(语法:将基本类型的值+“” 即可)

(2)String类型转基本数值类型(语法:s1.toInt、s1.toFloat、s1.toDouble、s1.toByte、s1.toLong、s1.toShort)


     
     
  1. object TestStringTransfer {
  2. def main(args: Array[ String]): Unit = {
  3. //(1)基本类型转String类型(语法:将基本类型的值+"" 即可)
  4. var str1: String = true + "你kin"
  5. println(str1)
  6. var str2: String = 4.444 + "拜拜"
  7. println(str2)
  8. var str3: String = 4444 + ""
  9. println(str3)
  10. //(2)String类型转基本数值类型(语法:调用相关API)
  11. var s1: String = "11"
  12. var n1: Byte = s1.toByte
  13. var n2: Short = s1.toShort
  14. var n3: Int = s1.toInt
  15. var n4: Long = s1.toLong
  16. println(s1)
  17. println(n1)
  18. println(n2)
  19. println(n3)
  20. println(n4)
  21. }
  22. }

(3)注意事项

在将String类型转成基本数值类型时,要确保String类型能够转成有效的数据,比如我们可以把"123",转成一个整数,但是不能把"hello"转成一个整数。

var n5:Int = “12.6”.toInt会出现NumberFormatException异常。

2.13 字符串String

Scala中本身没有String数据类型,字符串本质上是Java String。和Java String 一样,String是一个不可变对象,该对象不可修改。

三、运算符

Scala运算符的使用和Java运算符的使用基本相同,只有个别细节上不同。

3.1 算术运算符

1)基本语法

运算符

运算

范例

结果

+

正号

+3

3

-

负号

b=4; -b

-4

+

5+5

10

-

6-4

2

*

3*4

12

/

5/5

1

%

取模(取余)

7%5

2

+

字符串相加

“He”+”llo”

“Hello”

(1)对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。

(2)对一个数取模a%b,和Java的取模规则一样。

2)案例实操


     
     
  1. object TestArithmetic {
  2. def main(args: Array[ String]): Unit = {
  3. // 1)对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
  4. var r1: Int = 10 / 3
  5. println(r1) //3
  6. var r2: Double = 10 / 3
  7. println(r2) //3.0
  8. var r3: Double = 10.0 / 3
  9. println(r3) //3.3333333333333335
  10. println(r3.formatted( "%.2f")) //3.33 含义:保留小数点2位,使用四舍五入
  11. //(2)对一个数取模a%b,和Java的取模规则一样。
  12. var r4 = 10 % 3
  13. println(r4) //1
  14. }
  15. }

3.2 关系运算符(比较运算符)

1)基本语法

运算符

运算

范例

结果

==

相等于

4==3

false

!=

不等于

4!=3

true

<

小于

4<3

false

>

大于

4>3

true

<=

小于等于

4<=3

false

>=

大于等于

4>=3

true

2)案例实操

(1)需求1:


     
     
  1. object TestRelation {
  2. def main(args: Array[ String]): Unit = {
  3. // 测试:>、>=、<=、<、==、!=
  4. var a: Int = 2
  5. var b: Int = 1
  6. println(a > b) // true
  7. println(a >= b) // true
  8. println(a < b) // false
  9. println(a <= b) // false
  10. println( "a==b" + (a == b)) // false
  11. println(a != b) // true
  12. }
  13. }

(2)需求2:Java和Scala中关于==的区别

Java:==比较两个变量本身的值,即两个对象在内存中的首地址;equals比较字符串中所包含的内容是否相同。


     
     
  1. public class TestRelation2 {
  2. public static void main( String[] args) {
  3. String s1 = "hhhh";
  4. String s2 = new String( "hhhh");
  5. System.out.println(s1 == s2); // false
  6. System.out.println(s1.equals(s2)); // true
  7. }
  8. }

Scala:==更加类似于Java中的equals,参照jd工具


     
     
  1. object TestRelationScala {
  2. def main(args: Array[ String]): Unit = {
  3. val s1 = "aaa"
  4. val s2 = new String( "aaa")
  5. println(s1 == s2) // true
  6. println(s1.eq(s2)) // false
  7. }
  8. }

3.3 逻辑运算符

1)基本语法

用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个Boolean值。

假定:变量A为true,B为false

运算符

描述

实例

&&

逻辑与

(A && B) 运算结果为 false

||

逻辑或

(A || B) 运算结果为 true

!

逻辑非

!(A && B) 运算结果为 true

2)案例实操


     
     
  1. object TestLogic {
  2. def main(args: Array[ String]): Unit = {
  3. // 测试:&&、||、!
  4. var a = true
  5. var b = false
  6. println( "a&&b=" + (a && b)) // a&&b=false
  7. println( "a || b =" + (a || b)) // a || b =true
  8. println( "!(a&&b)" + (!(a && b))) // !(a&&b)true
  9. }
  10. }

3.4 赋值运算符

1)基本语法

赋值运算符就是将某个运算后的值,赋给指定的变量。

运算符

描述

实例

=

简单的赋值运算符,将一个表达式的值赋给一个左值

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

<<=

左移后赋值

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中没有++、–操作符,可以通过+=、-=来实现同样的效果;

2)案例实操


     
     
  1. object TestAssignment {
  2. def main(args: Array[ String]): Unit = {
  3. var r1 = 11
  4. // 没有++
  5. r1 += 1 //12
  6. println(r1)
  7. // 没有--
  8. r1 -= 2 //10
  9. println(r1)
  10. }
  11. }

3.5 位运算符

1)基本语法

下表中变量 a 为 60,b 为 13。

运算符

描述

实例

&

按位与运算符

(a & b) 输出结果 12 ,二进制解释: 0000 1100

|

按位或运算符

(a | b) 输出结果 61 ,二进制解释: 0011 1101

^

按位异或运算符

(a ^ b) 输出结果 49 ,二进制解释: 0011 0001

~

按位取反运算符

(~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。

<<

左移动运算符

a << 2 输出结果 240 ,二进制解释: 0011 0000

>>

右移动运算符

a >> 2 输出结果 15 ,二进制解释: 0000 1111

>>>

无符号右移

a >>>2 输出结果 15, 二进制解释: 0000 1111

2)案例实操


     
     
  1. object TestPositon {
  2. def main(args: Array[ String]): Unit = {
  3. // 测试:1000 << 1 =>10000
  4. var n1: Int = 8
  5. n1 = n1 << 1
  6. println(n1) // 16
  7. }
  8. }

3.6 Scala运算符本质

在Scala中其实是没有运算符的,所有运算符都是方法

1)当调用对象的方法时,点.可以省略

2)如果函数参数只有一个,或者没有参数,()可以省略


     
     
  1. object TestOpt {
  2. def main(args: Array[ String]): Unit = {
  3. // 标准的加法运算
  4. val i: Int = 1.+( 1)
  5. // (1)当调用对象的方法时,.可以省略
  6. val j: Int = 1 + ( 1)
  7. // (2)如果函数参数只有一个,或者没有参数,()可以省略
  8. val k: Int = 1 + 1
  9. println( 1.toString())
  10. println( 1 toString())
  11. println( 1 toString)
  12. }
  13. }

四、流程控制

4.1 分支控制if-else

让程序有选择的的执行,分支控制有三种:单分支、双分支、多分支

4.1.1 单分支

1)基本语法

if (条件表达式) {
执行代码块
}

说明:当条件表达式为ture时,就会执行{ }的代码。

2)案例实操

需求:输入人的年龄,如果该同志的年龄小于18岁,则输出“童年”


     
     
  1. if (age < 18){
  2.     println( "童年")
  3. }

4.1.2 双分支

1)基本语法

if (条件表达式) {
执行代码块1
} else {
执行代码块2
}

2)案例实操

需求:输入年龄,如果年龄小于18岁,则输出“童年”。否则,输出“成年”。


     
     
  1. if (age < 18) {
  2.     println( "童年")
  3. } else {
  4.     println( "成年")
  5. }

4.1.3 多分支

1)基本语法

if (条件表达式1) {
执行代码块1
}
else if (条件表达式2) {
执行代码块2
}
……
else {
执行代码块n
}

2)案例实操

(1)需求1:需求:输入年龄,如果年龄小于18岁,则输出“童年”。如果年龄大于等于18且小于等于30,则输出“中年”,否则,输出“老年”。


     
     
  1. if (age < 18) {
  2.     println( "童年")
  3. } else if (age >= 18 && age < 30) {
  4.     println( "中年")
  5. } else {
  6.     println( "老年")
  7. }

(2)需求2:Scala中if else表达式其实是有返回值的,具体返回值取决于满足条件的代码体的最后一行内容。


     
     
  1. val res : String = if (age < 18) {
  2.     "童年"
  3. } else if (age >= 18 && age < 30) {
  4.     "中年"
  5. } else {
  6.     "老年"
  7. }
  8. println(res)

(3)需求3:Scala中返回值类型不一致,取它们共同的祖先类型。


     
     
  1. val res : Any = if (age < 18) {
  2.     "童年"
  3. } else if (age >= 18 && age < 30) {
  4.     "中年"
  5. } else {
  6.     100
  7. }
  8. println(res)

(4)需求4:Java中的三元运算符可以用if else实现

如果大括号{}内的逻辑代码只有一行,大括号可以省略。如果省略大括号,if只对最近的一行逻辑代码起作用。


     
     
  1. // Java中三元运算符:a?b:c
  2. // 如:int result = flag ? 1 : 0
  3. // Scala
  4. val res:String = if(age>= 18) "成年" else "未成年"
  5. println(res)

4.2 嵌套分支

在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层。分支外面的分支结构称为外层分支。嵌套分支不要超过3层。

1)基本语法

if(){
if(){
}else{
}
}

2)案例实操

需求:如果输入的年龄小于18,返回“童年”。如果输入的年龄大于等于18,需要再判断:如果年龄大于等于18且小于30,返回“中年”;如果其他,返回“老年”。


     
     
  1. import scala.io.StdIn
  2. object TestIfElse {
  3. def main (args: Array[String]): Unit = {
  4. // Scala
  5. println( "input age:")
  6. var age = StdIn.readShort()
  7. val res: Any = if (age < 18) {
  8. "童年"
  9. } else {
  10. if (age >= 18 && age < 30) {
  11. "中年"
  12. } else {
  13. "老年"
  14. }
  15. }
  16. println(res)
  17. }
  18. }

4.3 Switch分支结构

在Scala中没有Switch,而是使用模式匹配来处理。

模式匹配涉及到的知识点较为综合,因此我们放在后面讲解。

4.4 For循环控制

Scala也为for循环这一常见的控制结构提供了非常多的特性,这些for循环的特性被称为for推导式或for表达式。

4.4.1 范围数据循环(To)

1)基本语法


     
     
  1. // java for循环语法
  2. for(int i = 0; i < 10; i++){
  3.     System.out.println( "i=" + i);
  4. }
  5. // scala for循环语法
  6. for(i <- 1 to 10){
  7.     println( "i=" + i)
  8. }
  9. // 输出:从1~10(包含 1 和 10 )

(1)i 表示循环的变量,<- 规定to

(2)i 将会从 1-3 循环,前后闭合

4.4.2 范围数据循环(Until)

1)基本语法


     
     
  1. // 方法一:
  2. for(i <- 1 until 10) {
  3. print( "i=" + i)
  4. }
  5. // 输出:从1~10(包含 1,不包含 10 )
  6. // 方法二:
  7. for(i <- Range( 1, 10)) {
  8. print( "i=" + i)
  9. }

(1)这种方式和前面的区别在于i是从1到3-1

(2)即使前闭合后开的范围

4.4.3 循环守卫

1)基本语法


     
     
  1. for(i <- 1 to 3 if i != 2) {
  2. print(i + " ")
  3. }

说明

(1)循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为true则进入循环体内部,为false则跳过,类似于continue。

(2)上面的代码等价


     
     
  1. for (i <- 1 to 3){
  2.     if (i != 2) {
  3. print(i + " ")
  4. }
  5. }

4.4.4 循环步长by

1)基本语法


     
     
  1. for (i <- 1 to 10 by 2) {
  2. println(“i=” + i)
  3. }

说明:by表示步长

2)案例实操

需求:输出1到10以内的所有奇数


     
     
  1. for (i <- 1 to 10 by 2) {
  2. println(“i=” + i)
  3. }
  4. 输出结果
  5. i= 1
  6. i= 3
  7. i= 5
  8. i= 7
  9. i= 9

4.4.5 嵌套循环

1)基本语法


     
     
  1. for(i <- 1 to 3; j <- 1 to 3) {
  2.     println( " i =" + i + " j = " + j)
  3. }

说明:没有关键字,所以范围后一定要加;来隔断逻辑

2)基本语法

上面的代码等价


     
     
  1. for (i <- 1 to 3) {
  2.     for (j <- 1 to 3) {
  3.         println(“i =” + i + " j=" + j)
  4.     }
  5. }

4.4.6 引入变量

1)基本语法


     
     
  1. for(i <- 1 to 3; j = 4 - i) {
  2. println( "i=" + i + " j=" + j)
  3. }

说明:

(1)for推导式一行中有多个表达式时,所以要加 ; 来隔断逻辑

(2)for推导式有一个不成文的约定:当for推导式仅包含单一表达式时使用圆括号,当包含多个表达式时,一般每行一个表达式,并用花括号代替圆括号,如下:


     
     
  1. for {
  2.     i <- 1 to 3
  3.     j = 4 - i
  4. } {
  5.     println(“i=” + i + " j=" + j)
  6. }

2)案例实操

上面的代码等价于


     
     
  1. for (i <- 1 to 3) {
  2.     var j = 4 - i
  3.     println(“i=” + i + " j=" + j)
  4. }

4.4.7 循环返回值

1)基本语法


     
     
  1. val res = for(i <- 1 to 10) yield i
  2. println(res)

说明:将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字

注意:开发中很少使用。

2)案例实操

需求:将原数据中所有值乘以2,并把数据返回到一个新的集合中。


     
     
  1. var res = for(i < -1 to 10) yield {
  2. i * 2
  3. }
  4. println(res)

输出结果:

Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

4.4.8 倒序打印

1)说明:如果想倒序打印一组数据,可以用reverse。

2)案例实操:

需求:倒序打印10到1


     
     
  1. for(i <- 1 to 10 reverse){
  2. println(i)
  3. }

4.5 While和do…While循环控制

While和do…While的使用和Java语言中用法相同。

4.5.1 While循环控制

1)基本语法


     
     
  1. 循环变量初始化
  2. while (循环条件) {
  3. 循环体(语句)
  4. 循环变量迭代
  5. }

说明:

(1)循环条件是返回一个布尔值的表达式

(2)while循环是先判断再执行语句

(3)与for语句不同,while语句没有返回值,即整个while语句的结果是Unit类型()

(4)因为while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量,而变量需要声明在while循环的外部,那么就等同于循环的内部对外部的变量造成了影响,所以不推荐使用,而是推荐使用for循环


     
     
  1. object For01 {
  2. def main(args: Array[ String]): Unit = {
  3. // 1.范围循环 To
  4. for (i <- 1 to 3)
  5. println( "生如")
  6. println( "to----------------------")
  7. // 2.范围循环 Unit
  8. for (i <- 1 until 3)
  9. println( "夏花")
  10. println( "until----------------------")
  11. // 3.循环守卫
  12. for (i <- 1 to 6) {
  13. if (i != 2) {
  14. println(i)
  15. }
  16. }
  17. println( "!=----------------------")
  18. // 4.循环步长 by
  19. for (i <- 1 to 6 by 2)
  20. println(i)
  21. println( "by----------------------")
  22. for (i <- -10 to -1 by 2)
  23. println(i)
  24. println( "by----------------------")
  25. // 5.循环嵌套
  26. for (i <- 1 to 4; j <- 1 to 6) {
  27. print( "i=" + i + ",j=" + j + "\t")
  28. if (j == 6)
  29. println()
  30. }
  31. println( "嵌套----------------------")
  32. // 6.引入变量
  33. for (i <- 1 to 10; j = 10 - i) {
  34. println( "i=" + i + ",j=" + j)
  35. }
  36. println( "引入变量----------------------")
  37. for {
  38. i <- 1 to 3
  39. j = 3 - i
  40. } {
  41. println( "i=" + i + ",j=" + j)
  42. }
  43. println( "引入变量----------------------")
  44. // 7.循环返回值
  45. val res = for (i <- 1 to 10) yield i
  46. println(res)
  47. println( "----------------------")
  48. //需求:将原数据中所有值乘以2,并把数据返回到一个新的集合中。
  49. var res1 = for (i <- 1 to 10) yield {
  50. i * 2
  51. }
  52. println(res1)
  53. println( "循环返回值----------------------")
  54. // 8.倒序打印
  55. for (i <- 1 to 10 reverse) {
  56. println(i)
  57. }
  58. println( "倒序----------------------")
  59. }
  60. }

4.5.2 do…while循环控制

1)基本语法


     
     
  1. 循环变量初始化;
  2. do{
  3. 循环体(语句)
  4. 循环变量迭代
  5. } while(循环条件)

说明

(1)循环条件是返回一个布尔值的表达式

(2)do…while循环是先执行,再判断

4.6 循环中断

1)基本说明

Scala内置控制结构特地去掉了break和continue,是为了更好的适应函数式编程,推荐使用函数式的风格解决break和continue的功能,而不是一个关键字。Scala中使用breakable控制结构来实现break和continue功能。

2)案例实操

需求1:采用异常的方式退出循环


     
     
  1. // 1.正常结束循环
  2. try {
  3. for (elem <- 1 to 10) {
  4. println(elem)
  5. if (elem == 5) throw new RuntimeException
  6. }
  7. } catch {
  8. case e =>
  9. }
  10. println( "正常结束循环")
  11. }

需求2:采用Scala自带的函数,退出循环


     
     
  1. // 2.采用scala自带的函数,退出循环
  2. Breaks.breakable(
  3.     for (e <- 1 to 5) {

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/30526.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据测试基本知识

常用大数据框架结构 1.大数据测试常用到的软件工具 工具推荐&#xff0c;对于测试数据构造工具有&#xff1a;Datafaker、DbSchema、Online test data generator等&#xff1b;ETL测试工具有&#xff1a;RightData、QuerySurge等&#xff1b;数据质量检查工具&#xff1a;great…

MySQL-SQL存储过程/触发器详解(上)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

Three.js--》实现3d地月模型展示

目录 项目搭建 初始化three.js基础代码 创建月球模型 添加地球模型 添加模型标签 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目中才能灵活将所学知识运用起来&#xff0c;话不多说直接开始。 项目搭建 本案例还…

《离散数学》:代数系统和图论导论

一、代数系统 代数系统是数学中的一个重要概念&#xff0c;它涉及一组对象以及定义在这些对象上的运算规则。代数系统可以是抽象的&#xff0c;也可以是具体的。 在抽象代数中&#xff0c;代数系统通常由一组元素和一组操作&#xff08;或称为运算&#xff09;组成。这些操作…

【MySQL新手入门系列四】:手把手教你MySQL数据查询由入门到学徒

SQL语言是与数据库交互的机制&#xff0c;是关系型数据库的标准语言。SQL语言可以用于创建、修改和查询关系数据库。SQL的SELECT语句是最重要的命令之一&#xff0c;用于从指定表中查询数据。在此博客中&#xff0c;我们将进一步了解SELECT语句以及WHERE子句以及它们的重要性。…

vue进阶-vue-route

Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得轻而易举。 本章只做学习记录&#xff0c;详尽的内容一定要去官网查看api文档 Vue Router-Vue.js 的官方路由 1. 路由的基本使用 1.1 安装vue-router npm install vue-…

SpringCloud Eureka注册中心高可用集群配置(八)

当注册中心扛不住高并发的时候&#xff0c;这时候 要用集群来扛&#xff1b; 我们再新建两个module microservice-eureka-server-2002 microservice-eureka-server-2003 第一步&#xff1a; pom.xml 把依赖加下&#xff1a; <dependencies> <dependency…

golang 协程的实现原理

核心概念 要理解协程的实现, 首先需要了解go中的三个非常重要的概念, 它们分别是G, M和P, 没有看过golang源代码的可能会对它们感到陌生, 这三项是协程最主要的组成部分, 它们在golang的源代码中无处不在. G (goroutine) G是goroutine的头文字, goroutine可以解释为受管理的…

Prompt 范式产业实践分享!基于飞桨 UIE-X 和 Intel OpenVINO 实现跨模态文档信息抽取

近期 Prompt 范式备受关注&#xff0c;实际上&#xff0c;其思想在产业界已经有了一些成功的应用案例。中科院软件所和百度共同提出了大一统诸多任务的通用信息抽取技术 UIE&#xff08;Universal Information Extraction&#xff09;。截至目前&#xff0c;UIE 系列模型已发布…

Selenium 相对定位

目录 前言&#xff1a; 相对定位 工作原理 可用的相对定位 Above Below Left of Right of Near 链式相对定位 相对于WebElement的相对定位 实例演示 前言&#xff1a; Selenium传统定位基本能解决80%的定位需求&#xff0c;但是还是有一些复杂场景传统定位定不到的…

express框架学习笔记

express简介 express是一个基于Node.js平台的极简的、灵活的WEB应用开发框架。express是一个封装好的工具包&#xff0c;封装了很多功能&#xff0c;便于我们开发WEB应用&#xff08;HTTP服务&#xff09; express使用 新建express文件夹新建文件test01.js&#xff0c;代码如…

深蓝学院C++基础与深度解析笔记 第 5 章 语句

1. 语句基础 ● 语句的常见类别 – 表达式语句&#xff1a;表达式后加分号&#xff0c;对表达式求值后丢弃&#xff0c;可能产生副作用 – 空语句&#xff1a;仅包含一个分号的语句&#xff0c;可能与循环一起工作 – 复合语句&#xff08;语句体&#xff09;&#xff1a;由大…

电商数仓(用户行为采集平台)数据仓库概念、用户行为日志、业务数据、模拟数据、用户行为数据采集模块、日志采集Flume

1、数据仓库概念 数据仓库&#xff08; Data Warehouse &#xff09;&#xff0c;是为企业制定决策&#xff0c;提供数据支持的。可以帮助企业&#xff0c;改进业务流程、提高产品质量等。 数据仓库的输入数据通常包括&#xff1a;业务数据、用户行为数据和爬虫数据等。 业务数…

流场粒子追踪精度数值实验

在计算流线&#xff0c;拉格朗日拟序结构等流场后处理时&#xff0c;我们常常需要计算无质量的粒子在流场中迁移时的轨迹&#xff0c;无质量意味着粒子的速度为流场当地的速度。此时&#xff0c;求解粒子的位移这个问题是一个非常简单的常微分方程问题。 假设流场中存在 i 个粒…

Java版本+企业电子招投标系统源代码之电子招投标系统建设的重点和未来趋势

计算机与网络技术的不断发展&#xff0c;推动了社会各行业信息化的步伐。时至今日&#xff0c;电子政务、电子商务已经非常普及&#xff0c;云计算、大数据、工业4.0、“互联网”等发展理念也逐步深入人心&#xff0c;如何将传统行业与互联网科技有效结合起来&#xff0c;产生1…

Vue实现元素沿着坐标数组移动,超出窗口视图时页面跟随元素滚动

一、实现元素沿着坐标数组移动 现在想要实现船沿着下图中的每个河岸移动。 实现思路&#xff1a; 1、将所有河岸的位置以 [{x: 1, y: 2}, {x: 4, y: 4}, …] 的形式保存在数组中。 data() {return {coordinateArr: [{ x: 54, y: 16 }, { x: 15, y: 31 }, { x: 51, y: 69 }…

升级Nginx

目录 前言 一、升级Nginx 1&#xff09;首先在官网下载一个新版本的Nginx 2&#xff09;首先将下载的压缩包进行解包 3&#xff09;进入已解包的目录中 4&#xff09;配置安装路径 5&#xff09;make 6&#xff09;备份原来Nginx的资源 7&#xff09;重启Nginx服务 8&#…

【2023最全教程】Web自动化测试怎么做?Web自动化测试的详细流程和步骤

一、什么是web自动化测试 自动化&#xff08;Automation&#xff09;是指机器设备、系统或过程&#xff08;生产、管理过程&#xff09;在没有人或较少人的直接参与下&#xff0c;按照人的要求&#xff0c;经过自动检测、信息处理、分析判断、操纵控制&#xff0c;实现预期的目…

毕业季Android开发面试,有哪些常见的题?

前言 对于计算机行业早已烂大街&#xff0c;随之而来的毕业季。还会有大批的程序员涌进来&#xff0c;而我们想要继续进入Android开发岗位的人员&#xff0c;最先考虑的是面试。面试题是我们决定踏进工作的重要环节。 对于刚毕业的实习生来说&#xff0c;如何在应聘中脱颖而出…

LightningChart .NET 10.5.1 Crack LightningChart 2023

LightningChart .NET v.10.5.1 已经发布&#xff01; DataCursor 和 3D TransparencyRenderMode 现在可用。 为所有 3D、Polar 和 Smith 系列启用 DataCursor 在早期阶段&#xff0c;LightningChart 提供了不同的工具&#xff0c;需要用户编写额外的代码才能启用数据跟踪功能。…