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这门语言。
Scala完全面向对象,故Scala去掉了Java中非面向对象的元素,如static关键字,void类型
1)static Scala无static关键字,由object实现类似静态方法的功能(类名.方法名)。
2)void 对于无返回值的函数,Scala定义其返回值类型为Unit类
官方编程指南 1)
在线查看:https://www.scala-lang.org
Scala 注释使用和 Java 完全一样。
(1)单行注释://
(2)多行注释:/* */
(3)文档注释:/** * */
代码规范
(1)使用一次 tab 操作,实现缩进,默认整体向右边移动,用 shift+tab 整体向左移
(2)或者使用 ctrl + alt + L 来进行格式化
(3)运算符两边习惯性各加一个空格。比如:2 + 4 * 5。
(4)一行最长不超过 80 个字符,超过的请使用换行展示,尽量保持格式优雅
变量和常量(重点)
0)回顾:
Java 变量和常量语法
变量类型 变量名称 = 初始值 int a = 10
final 常量类型 常量名称 = 初始值 final int b = 20
1)Scala 变量和常量语法
var 变量名 [: 变量类型] = 初始值 var i:Int = 10
val 常量名 [: 常量类型] = 初始值 val j:Int = 20
注意:能用常量的地方不用变量
(1)声明变量时,类型可以省略,编译器自动推导,即类型推导
(2)类型确定后,就不能修改,说明 Scala 是强数据类型语言。
(3)变量声明时,必须要有初始值
(4)在声明/定义一个变量时,可以使用 var 或者 val 来修饰,var 修饰的变量可改变, val 修饰的变量不可改。
def main(args: Array[String]): Unit = { //(1)声明变量时,类型可以省略,编译器自动推导,即类型推导 var age = 18 age = 30 //(2)类型确定后,就不能修改,说明 Scala 是强数据类型语言。 // age = "tom" // 错误 //(3)变量声明时,必须要有初始值 // var name //错误 //(4)在声明/定义一个变量时,可以使用 var 或者 val 来修饰,var 修饰 的变量可改变,val 修饰的变量不可改。 var num1 = 10 // 可变 val num2 = 20 // 不可变 num1 = 30 // 正确 //num2 = 100 //错误,因为 num2 是 val 修饰的 }
(5)var 修饰的对象引用可以改变,val 修饰的对象则不可改变,但对象的状态(值) 却是可以改变的。(比如:自定义对象、数组、集合等等)
object TestVar { def main(args: Array[String]): Unit = { // p1 是 var 修饰的,p1 的属性可以变,而且 p1 本身也可以变 var p1 = new Person() p1.name = "dalang" p1 = null // p2 是 val 修饰的,那么 p2 本身就不可变(即 p2 的内存地址不能变), 但是,p2 的属性是可以变,因为属性并没有用 val 修饰。 val p2 = new Person() p2.name="jinlian" // p2 = null // 错误的,因为 p2 是 val 修饰的 } } class Person{ var name : String = "jinlian" }
标识符的命名规范
Scala 对各种变量、方法、函数等命名时使用的字符序列称为标识符。即:凡是自己可 以起名字的地方都叫标识符。
1)命名规则 Scala 中的标识符声明,基本和 Java 是一致的,但是细节上会有所变化,有以下三种规 则:
(1)以字母或者下划线开头,后接字母、数字、下划线
(2)以操作符开头,且只包含操作符(+ - * / # !等)
(3)用反引号`....`包括的任意字符串,即使是 Scala 关键字(39 个)也可以
字符串输出
1)基本语法
(1)字符串,通过+号连接
(2)printf 用法:字符串,通过%传值。
(3)字符串模板(插值字符串):通过$获取变量值
object test { def main(args: Array[String]): Unit = { var name: String = "jinlian" var age: Int = 18 //(1)字符串,通过+号连接 println(name + " " + age) //(2)printf 用法字符串,通过%传值。 printf("name=%s age=%d\n", name, age) //(3)字符串,通过$引用 //多行字符串,在 Scala中,利用三个双引号包围多行字符串就可以实现。 //输入的内容,带有空格、\t 之类,导致每一行的开始位置不能整洁对齐。 //应用 scala 的 stripMargin 方法,在 scala 中 stripMargin 默认 //是“|”作为连接符,//在多行换行的行头前面加一个“|”符号即可。 val s = """ |select |name, |age |from user |where name="zhangsan" """.stripMargin println(s) //如果需要对变量进行运算,那么可以加${} val s1 = s""" |select | name, | age |from user |where name="$name" and age=${age+2} """.stripMargin println(s1) val s2 = s"name=$name" println(s2) } }
键盘输入
在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。
def main(args: Array[String]): Unit = { // 1 输入姓名 println("input name:") var name = StdIn.readLine() // 2 输入年龄 println("input age:") var age = StdIn.readShort() // 3 输入薪水 println("input sal:") var sal = StdIn.readDouble() // 4 打印 println("name=" + name) println("age=" + age) println("sal=" + sal) }
位移运算符
a 为 60
<< 左移动运算符 a << 2 输出结果 240 ,二进制解释: 0011 0000 >>
右移动运算符 a >> 2 输出结果 15 ,二进制解释: 0000 1111
Scala 运算符本质
在 Scala 中其实是没有运算符的,所有运算符都是方法。
1)当调用对象的方法时,点.可以省略
2)如果函数参数只有一个,或者没有参数,()可以省略
def main(args: Array[String]): Unit = { // 标准的加法运算 val i:Int = 1.+(1) // (1)当调用对象的方法时,.可以省略 val j:Int = 1 + (1) // (2)如果函数参数只有一个,或者没有参数,()可以省略 val k:Int = 1 + 1
}
流程控制
分支控制有三种:单分支、双分支、多分支
//单分支
if (条件表达式) { 执行代码块 }
//双分支 if (条件表达式) { 执行代码块 1 } else { 执行代码块 2 }
//多分支 if (条件表达式 1) { 执行代码块 1 } else if (条件表达式 2) { 执行代码块 2 } …… else { 执行代码块 n }
值得注意的是,Scala 中 if else 表达式其实是有返回值的,具体返回值取决于满足条件的 代码体的最后一行内
def main(args: Array[String]): Unit = { println("input age") var age = StdIn.readInt() val res :String = if (age < 18){ "童年" }else if(age>=18 && age<30){ "中年" }else{ "老年" } println(res) }
Switch 分支结构
在 Scala 中没有 Switch,而是使用模式匹配来处理。
For 循环控制
Scala 也为 for 循环这一常见的控制结构提供了非常多的特性,这些 for 循环的特性被称 为 for 推导式或 for 表达式。
范围数据循环(To)
for(i <- 1 to 3){ print(i + " ") } println() //(1)i 表示循环的变量,<- 规定 to //(2)i 将会从 1-3 循环,前后闭合
范围数据循环(Until)
for(i <- 1 until 3) { print(i + " ") } println() //(1)这种方式和前面的区别在于 i 是从 1 到 3-1 //(2)即使前闭合后开的范围
循环守卫
for(i <- 1 to 3 if i != 2) { print(i + " ") } println() //(1)循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为 true //则进入循环体内部,为 false 则跳过,类似于 continue。
上面的代码等价
for (i <- 1 to 3){ if (i != 2) { print(i + " ") } }
循环步长
for (i <- 1 to 10 by 2) { println("i=" + i) } //说明:by 表示步长 //输出结果 i=1 i=3 i=5 i=7 i=9
嵌套循环
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 =" + i + " j=" + j) } }
引入变量
for(i <- 1 to 3; j = 4 - i) { println("i=" + i + " j=" + j) } //(1)for 推导式一行中有多个表达式时,所以要加 ; 来隔断逻辑 //注意与嵌套循环在做区分,嵌套循环中j与i没有关系,而本循环中,j 是根据 i 的取值而来的
for 推导式有一个不成文的约定:当 for 推导式仅包含单一表达式时使用圆括号, 当包含多个表达式时,一般每行一个表达式,并用花括号代替圆括号,如下
for { i <- 1 to 3 j = 4 - i } { println("i=" + i + " j=" + j) }
上面的代码等价于
for (i <- 1 to 3) { var j = 4 - i println("i=" + i + " j=" + j) }
循环返回值
val res = for(i <- 1 to 10) yield i println(res) //说明:将遍历过程中处理的结果返回到一个新 Vector 集合中,使用 yield 关键字。 //注意:开发中很少使用。
While 和 do..While 循环控制
(1)循环条件是返回一个布尔值的表达式
(2)while 循环是先判断再执行语句
(3)与 for 语句不同,while 语句没有返回值,即整个 while 语句的结果是 Unit 类型()
(4)因为 while 中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免 的使用变量,而变量需要声明在 while 循环的外部,那么就等同于循环的内部对外部的变量 造成了影响,所以不推荐使用,而是推荐使用 for 循环。
循环中断
Scala 内置控制结构特地去掉了 break 和 continue,是为了更好的适应函数式编程,推 荐使用函数式的风格解决break和continue的功能,而不是一个关键字。
Scala中使用breakable 控制结构来实现 break 和 continue 功能。
import scala.util.control.Breaks def main(args: Array[String]): Unit = { Breaks.breakable( for (elem <- 1 to 10) { println(elem) if (elem == 5) Breaks.break() } ) println("正常结束循环") } //:对 break 进行省略,注意观察导报对象的不同 import scala.util.control.Breaks._ object TestBreak { def main(args: Array[String]): Unit = { breakable { for (elem <- 1 to 10) { println(elem) if (elem == 5) break } } println("正常结束循环") } }
//:循环遍历 10 以内的所有数据,奇数打印,偶数跳过(continue) object TestBreak { def main(args: Array[String]): Unit = { for (elem <- 1 to 10) { if (elem % 2 == 1) { println(elem) } else { println("continue") } } } }
以上总结根据尚硅谷Scala笔记