变量和数据类型
1.注释
Scala注释使用和Java完全一样。注释是一个程序员必须要具有的良好编程习惯。将自己的思想通过注释先整理出来,再用代码去体现。
//单行注释
/*
多行注释
*/
/**
* doc注释
*/
2.变量
变量是一种使用方便的占位符,用于引用计算机内存地址,变量创建后会占用一定的内存空间。基于变量的数据类型,操作系统会进行内存分配并且决定什么将被储存在保留内存中。因此,通过给变量分配不同的数据类型,你可以在这些变量中存储整数,小数或者字母。
2.1 变量的声明
语法:
var 变量名 : 变量类型 = 变量值
val 变量名 : 变量类型 = 变量值
代码演示:
object Scala01_Var {
def main(args: Array[String]): Unit = {
//todo 1.var 声明的变量是可以修改的
var name : String = "zhangsan"
name = "wangwu"
//todo 2.val 声明的变量是不能修改的
val username : String = "lisi"
//username = "zhaoliu"
//todo 3.可以根据变量值的类型推断出变量类型,那么声明中可以省略类型
val age = 18
}
}
小结:
1.var 声明的变量是可以修改的
2.val 声明的变量是不能修改的
3.变量的类型如果能够通过变量值推断出来,那么可以省略类型声明
- 这里的省略,并不是不声明,而是由Scala编译器在编译时自动声明编译的;
- 并且,多态的时候是不能省略的
补充:常量的理解
java中 final修饰的变量称之为不可变变量
常量:1,“abc” , true 等这写值才是常量
(1)编译器可以执行常量计算
byte b = 10 + 10
常量的运算在编译之前就执行完了,变量b 编译成.class的时候直接存储的就是20,因为20在byte范围内,所以此代码不会报错
(2)变量的运算
byte b1 = 10;
byte b = b1 + 10;//编译报错
变量的值只有在运算的时候才能确定,编译的时候不知道变量值是多少;由于变量b1和10进行运算,需要提升b1为int类型,因此左边byte类型不兼容,因此编译不通过
2.2 变量的初始化
- Java语法中变量只要在使用前进行初始化就可以
可以参考:javaSE_局部变量 - Scala语法中是不允许的,必须显示进行初始化操作。
object ScalaVariable {
def main(args: Array[String]): Unit = {
var username // Error
val username = "zhangsan" // OK
}
}
2.3 可变变量 & 不可变变量
2.3.1可变变量
- 值可以改变的变量,称之为可变变量
- 变量类的型无法发生改变
- Scala中可变变量使用关键字var进行声明
object ScalaVariable {
def main(args: Array[String]): Unit = {
// 用户名称
var username : String = "zhangsan"
username = "lisi" // OK
username = true // Error
}
}
2.2.4 不可变变量
- 值一旦初始化后无法改变的变量,称之为不可变变量
- Scala中不可变变量使用关键字val进行声明, 类似于Java语言中的final关键字
object ScalaVariable {
def main(args: Array[String]): Unit = {
// 用户名称
val username : String = "zhangsan"
username = "lisi" // Error
username = true // Error
}
}
3.标识符
范式:规范和形式
Scala是多范式的编程语言;
Scala 可以使用两种形式的标志符,字符数字和符号。
-
和java一样,可以由数字、字母、
_
、$
组成,数字不能开头 -
Scala 的命名规范采用和 Java 类似的 camel 命名规范,首字符小写,比如 toString
-
Scala还可以使用由符号组成的标识符
// 和Java一样的标识符命名规则
val name = "zhangsan" // OK
val name1 = "zhangsan0" // OK
//val 1name = "zhangsan0" // Error
val name$ = "zhangsan1" // OK
val $name = "zhangsan2" // OK
val name_ = "zhangsan3" // OK
val _name = "zhangsan4" // OK
val $ = "zhangsan5" // OK
val _ = "zhangsan6" // OK
//val 1 = "zhangsan6" // Error
//val true = "zhangsan6" // Error
// 和Java不一样的标识符命名规则
val + = "lisi" // OK
val - = "lisi" // OK
val * = "lisi" // OK
val / = "lisi" // OK
val ! = "lisi" // OK
//val @ = "lisi" // Error
val @@ = "lisi" // OK
//val # = "lisi" // Error
val ## = "lisi" // OK
val % = "lisi" // OK
val ^ = "lisi" // OK
val & = "lisi" // OK
//val ( = "lisi" // Error
//val ( = "lisi" // Error
//val ) = "lisi" // Error
//val = = "lisi" // Error
val == = "lisi" // OK
//val [ = "lisi" // Error
//val ] = "lisi" // Error
//val : = "lisi" // Error
val :: = "lisi" // OK
//val ; = "lisi" // Error
//val ' = "lisi" // Error
//val " = "lisi" // Error
val "" = "lisi" // OK
val < = "lisi" // OK
val > = "lisi" // OK
val ? = "lisi" // OK
val | = "lisi" // OK
val \ = "lisi" // OK
//val ` = "lisi" // Error
val ~ = "lisi" // OK
val :-> = "wangwu" // OK
val :-< = "wangwu" // OK
// 切记,能声明和能使用是两回事
说明1
Scala 使用符号作为标识符的时候,其底层会将符号转义成$
开头的标识符;
可以在反编译的.java文件中可以查看符号转义成什么;
比如:->
使用 $colon$minus$greater
来表示这个符号。
说明2:
由于字符会被反编译成以$
开头的标识符,因此为保留的 Scala 编译器产生的标志符使用,应用程序应该避免使用$
开始的标识符,以免造成冲突。
还应该避免使用以下划线结尾的标志符以避免冲突。
- Scala 中的标识符也不能是关键字或保留字
4.数据类型
Scala与Java有着相同的数据类型,但是又有不一样的地方
4.1 Java数据类型
Java的数据类型包含基本类型和引用类型
- 基本类型:byte,short,char,int,long,float,double,boolean
- 引用类型:Object,数组,字符串,包装类,集合,POJO对象等
4.2 Scala数据类型
Scala是完全面向对象的语言,所以不存在基本数据类型的概念,有的只是任意值对象类型(AnyVal)和任意引用对象类型(AnyRef)
- 图中实线箭头是子父关系,虚线是可以进行隐式转换,并无子父关系;
- String类型属于java classes 并不是这里的StringOops
- Unit类型对象是
()
Java中64位数据类型的数值参与计算是分为两步,并非原子性的,先计算高32位,后计算低32位;
AnyRef 对象是()
AnyRef包含:
- Scala集合类
- Java类
包含String类型
- Scala类
- NULL类型 对象是
null
注意NULL是引用数据类型,因此不可以将null赋给值类型对象
比如:
val i : Int = null
Any类型既可以充当值类型 也可以充当 引用类型
Nothing: 表示没有正常值返回、异常
Unit:表示没有返回值
def test() : Nothing = {
throw new Exception
}
5.类型转换
5.1 自动类型转化(隐式转换)
1.数字默认为Int类型
2.如果想限定类型,类型不能省略
隐式转换可以参考数据类型图中的虚线
object ScalaDataType {
def main(args: Array[String]): Unit = {
val b : Byte = 10
val s : Short = b
val i : Int = s
val lon : Long = i
val c : Char = 'A'
val c1 : Int = c
}
}
需要注意一点:
Scala中值类型也是对象类型,因此隐式转换看起来有点像多态;
但是Scala中值数据类型之间是没有继承关系的,所以这里并非多态
这里隐式转换是马丁在编写编译器的时候帮助我们进行了转换;
思考题
object Scala03_DataType2 {
def main(args: Array[String]): Unit = {
val c : Char = 'A' + 1
println(c)
}
}
打印结果为B;不会报错
认为报错的原因:左边是char类型,右边是Int类型
正解:右边是两个常量相加,在编译期间就计算完了,因此在字节码文件中,c直接存储’B’,因此不会报错;
5.2 强制类型转化
- Java语言
int a = 10
byte b = (byte)a
- Scala语言
var a : Int = 10
Var b : Byte = a.toByte
由于Scala是完全面向对象的,而各种值类型之间又没有父子关系,因此Scala中做强制转换只能使用方法
基本上Scala的AnyVal类型之间都提供了相应转换的方法
5.3 字符串类型转化
scala是完全面向对象的语言,所有的类型都提供了toString方法,可以直接转换为字符串
lon.toString
任意类型都提供了和字符串进行拼接的方法
val i = 10
val s = "hello " + i