Scala 语言学习
变量
var 关键字定义的变量在声明后,可以进行修改
val 关键字定义的变量在声明之后,不可以进行修改(相当于Java中的 final 关键字)
final 关键字说明:声明的变量的地址不可变的,但是内存地址指向的内容是可以变的,但是Java中String没有提供修改内容的方法,都是创建一个新的字符串进行返回。
能省则省:
scala为了让开发过程变得简单, 可以将自动推断出来的内容省略。
val name=“wangwu”
变量声明时,需要显示初始化。
Scala数据类型介绍
- Scala与Java有着相同的数据类型,在Scala中数据类型都是对象,也就是说scala没有java中的原生(基本)类型。
- Scala数据类型分为两大类AnyVal(值类型)和AnyRef(引用类型),注意:不管是AnyVal还是AnyRef都是对象。
- 相对于Java的类型系统,scala要复杂一些!也正是这复杂多变的类型系统才让面向对象编程和函数式编程完美的融合在了一起。
虚线代表隐式自动装换。
Byte 8位 1个字节
Short 16位 2个字节
Int 32位 4个字节
Long 64位 8个字节
Float 32位 4个字节
Double 64位 8个字节
Char 16位 (转换成数字时,没有负数,所以Byte 没有办法转换成Char)
// JAVA中的八大基本数据类型
// byte short int long float double boolean char
// Scala是完全面向对象的语言,所以没有基本数据类型
val b:Byte = 10
val s:Short = 30
val i:Int = 10
val log: Long=10
val f:Float = 10.0f
val d:Double = 10.00
val bln:Boolean = true
val c:Char = 'c'
// 包装类 无缝衔接Java
val ii:Integer = 1024
数值类型转换
def main(args: Array[String]): Unit = {
println(30.toByte)
println(103.toChar)
println(30.toDouble)
println(30.toFloat)
println(30.toInt)
println(30.toLong)
println(30.toShort)
println(30.toBinaryString)
println('g'.toInt)
}
结果:
30
g
30.0
30.0
30
30
30
11110
103
Process finished with exit code 0
字符类型使用细节
char类型的数值可以自动隐士转换成int类型,但是,int类型无法自动转换成char类型,会损失精度。
var c2:Char = 'a' + 1 /*不正确*/
var c2:Int = 'a' + 1 /*正确*/
Unit类型、Null类型和Nothing类型
使用细节和注意事项
1.Null类只有一个实例对象,null,类似于Java中的null引用。null可以赋值给任意引用类型(AnyRef),但是不能赋值给值类型(AnyVal:比如Int,Float,Char,Boolean,Long,Double, Byte, Short)
2.Unit类型用来标识过程,也就是没有明确返回值的函数。由此可见,Unit类似于Java里的void。Unit只有一个实例,(),这个实例也没有实质的意义。
3.Nothing,可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容。
值类型和String类型的转换
- 基本类型转String类型
String str1 = true + "";
String str2 = 4.45 + "";
String str3 = 100 + "";
- String类型转基本数据类型
String s1 = "12"
s1.toInt
s1.toFloat
s1.toDouble
s1.toByte
s1.toLong
s1.toShort
注意事项
在将String 类型转成 基本数据类型时,要确保String类型能够转成有效的数据,比如 我们可以把 “123” , 转成一个整数,但是不能把 “hello” 转成一个整数
Scala中的下划线有特殊的用途,不能像Java中独立地当成变量名来使用
Scala 运算符
算数运算符
scala中没有 ++ --操作符,需要通过 += 、 -=来实现同样的效果,以避免出现歧义!!
注意
i = i+1 ,如果i为Byte 类型, +1之后会提升到Int类型,此时就会报错!!
object Operration {
def main(args: Array[String]): Unit = {
var i : Byte = 1
i += 1
println(i)
}
}
关系运算符
==, !=, <, >, <=, >=
赋值运算符
键盘输入语句
object Operration {
def main(args: Array[String]): Unit = {
var i = StdIn.readLine() //键盘输入语句, 标准化IO
println(i)
}
}
试题:交换两个变量的值,不能使用临时变量
object Sweap {
def main(args: Array[String]): Unit = {
var a = 10
var b = 20
println(s"${a}----${b}")
a = a + b
b = a - b
a = a - b
println(s"${a}----${b}")
}
}
/*输出结果:
10----20
20----10
Process finished with exit code 0
也可以使用 异或:^ 来实现*/
a = a ^ b
b = a ^ b
a = a ^ b
println(s"${a}----${b}")
程序流程控制
类似于Java,具体语法略
顺序控制, 分支控制, 循环控制
scala中的任意表达式都是有返回值的, 具体返回结果的值取决于满足条件的代码体的最后一行内容
scala中没有三元运算符,可以通过 if XX else XXX 代替
var s = if(flag) "a" else "b"
scala中没有switch,而是使用模式匹配来处理,后面有专题详解
for循环控制
Scala也为for循环这一常见的控制结构提供了非常多的特性,这些for循环的特性被称为for推导式或者for表达式
object ForTest {
def main(args: Array[String]): Unit = {
//TODO Scala中的for循环
for(i <- 1 to 5){
println(s"i=${i}")
}
}
}
输出:
i=1
i=2
i=3
i=4
i=5
Process finished with exit code 0
1 to 5 表示范围,包括 1 和 5(左右闭合)
for (i <- 1 until 5) {
println(s"i=${i}")
}
1 until 5 表示范围,包括 1 但不包括 5(左闭右开)
使用for循环控制时,可以使用{} 代替小括号()
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 (i <- Range(1, 10, 1)) {
print(i)
}
scala一道小面试题:使用一层循环,实现“九层妖塔”(杨辉三角阉割版)
预期结果:
*
***
*****
*******
*********
***********
*************
***************
*****************
for (index <- Range(1, 18, 2)) {
println(" " * ((18 - index) / 2) + "*" * index + " " * ((18 - index) / 2))
}
步长也可以通过 by来实现:
for (i <- 1 to 10 by 2) {
println("i=" + i)
}
循环守卫
循环守卫,即循环保护式(也称条件判断式,守卫)。保护式为true时进入循环体内部,为false时则跳过,类似于continue。
for(i <- 1 to 15 if i%2 !=0)
{
.....循环体内部
}
循环条件处可以引入变量
for (i <- 1 to 10 if i%2==0; j=i*2)
{
print(j)
}
// 第二种写法
for {
i <- 1 to 10
j=i*2 if i%2==0
}
{
print(j)
}
结果:
48121620
scala 中尽量不要使用 分号;可以使用{}与换行来实现 多条语句
循环返回值
正常的循环是没有返回值的(unit),但是使用yield可以将遍历过程中处理的结果返回到一个新Vector集合中。
def main(args: Array[String]): Unit = {
val value: IndexedSeq[Int] = for (i <- 1 to 10) yield i * 2
print(value)
}
def main(args: Array[String]): Unit = {
val value: IndexedSeq[Int] = for (i <- 1 to 10) yield
{
i * 2
}
print(value)
}
结果:
Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
Process finished with exit code 0
while循环的中断
Scala内置控制结构特地去掉了 break 和 continue,是为了更好的适应函数化编程,推荐使用函数式的风格解决break和continue的功能,而不是一个关键字。
完全面向对象:Breaks.break(): 会抛出异常,以实现中断整个循环
import scala.util.control.Breaks._
object hello {
def main(args: Array[String]): Unit = {
while (true)
{
break()
}
}
}
import scala.util.control.Breaks
object hell {
def main(args: Array[String]): Unit = {
for (i <- 1 to 10) {
if (i%5==0){
Breaks.break()
}
else
{
println(i)
}
}
print("循环结束")
}
}
结果:
1
2
3
4
Exception in thread "main" scala.util.control.BreakControl
从结果可以看出,break()是通过抛出异常来实现中断整个循环,这不是我们想要的结果
因此,为了中断循环后还可以继续执行后续代码,将需要循环的部分放入到Breaks.breakable()中
当有多条语句时可以将()变成{ }
break的()可以省略(import scala.util.control.Breaks._)
def main(args: Array[String]): Unit = {
Breaks.breakable{
for (i <- 1 to 10) {
if (i%5==0){
Breaks.break()
}
else
{
println(i)
}
}
}
print("循环结束")
}
结果:
1
2
3
4
循环结束
Process finished with exit code 0