1 变量和常量
声明变量时,类型可以省略,编译器自动推导,即类型推导
类型确定后,就不能修改,Scala是强数据类型语言
声明时,必须要有初始值
在声明/定义一个变量时,可以使用var或者val来修饰,var修饰的变量可改变,val修饰的变量不可改
var修饰的对象引用可以改变,val修饰的对象不可改变,但对象的状态(值)确是可以改变的
1.1 变量
var 变量名 [:变量类型] = 初始值
var i: Int = 10
var a = 10
1.2 常量
val 常量名 [:常量类型] = 初始值
val j: Int = 20
val b = 15
能用常量的地方不用变量
- 类型确定了就不能更改
- val修饰的对象不可改变
但对象的状态可以改变
class Student(val name: String, var age: Int) {
def printInfo(): Unit = {
// school这个属性在Java中是static的,全局只有一份
println(name + " " + age + " " + Student.school)
}
}
// 引入伴生对象
object Student {
val school: String = "aaa"
def main(args: Array[String]): Unit = {
val a = new Student("aaaa", 20)
// val修饰的对象不可改变
// a = new Student("bbbb", 20)
// age的属性是可变的,属性用var修饰
a.age = 22
// name的属性是不可变的,属性用val修饰
// a.name = "cccc"
}
}
2 标识符
命名规则
- 以字母或者下划线开头,后接字母、数字、下划线
- 以操作符开头,且只包含操作符(+- * / # !)等 如:val ++++ = 10
- 用反引号
...
包括的任意字符串,即使是Scala关键字也可以 valclass
= 111package, import, class, object , trait , extends, with , type, for 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 字符串输出
基本语法:
字符串,通过+连接
- printf用法:字符串,通过%传值
字符串模板(插值字符串):通过$获取变量值
object Test04_String { def main(args: Array[String]): Unit = { val name: String = "aa" val age: Int = 18 // 字符串通过+连接 println(age + "岁的" + name) // 18岁的aa // *用于将一个字符串复制多次并拼接 println(name * 3) // aaaaaa // printf用法:字符串,通过%传值 printf("%d岁的%s", age, name) // 18岁的aa (没有换行) println() // 换行 // 字符串模板(插值字符串):通过$获取变量值 // s"" 标识模板字符串 println(s"${age}岁的${name}") val num: Double = 2.2345 // 格式化模板字符串 println(f"The num is ${num}%2.2f") // The num is 2.23 // 原样输出 println(raw"The num is ${num}%2.2f") // The num is 2.2345%2.2f // 三引号表示字符串,保持多行字符串的原格式输出 val sql = s""" |select * |from | student |where | name = ${name} |""".stripMargin println(sql) } }
4 键盘输入
基本语法:
StdIn.readLine()、StdIn.readShort、StdIn.readDouble() ```scala import scala.io.StdIn
object Test05_StdIn { def main(args: Array[String]): Unit = { val name: String = StdIn.readLine() val age: Int = StdIn.readInt()
println(s"欢迎${age}岁的${name}")
} }
<a name="jet8p"></a>
# 5 文件输入输出
1. 从文件读取数据
```scala
object Test06_FileIO {
def main(args: Array[String]): Unit = {
// 从文件中读取数据
Source.fromFile("src/main/resources/test.txt").foreach(print)
}
}
- 将数据写入文件
object Test06_FileIO { def main(args: Array[String]): Unit = { // 将数据写入文件,调用JavaIO val writer = new PrintWriter(new File("src/main/resources/out.txt")) writer.write("hello scala from java writer") writer.close() } }
6 数据类型
- Scala中一切数据都是对象,是Any的子类
- Scala中数据类型分为两大类:数值类型(AnyVal)和引用类型(AnyRef)
- 低精度的值类型向高精度值类型自动转换
- StringOps是对Java中的String增强
- Unit:对应Java中的void,用于方法返回值的位置,表示方法没有返回值。Unit是一个数据类型,只有一个对象()。、
- Null是一个类型,只有一个对象null,是所有引用类型(AnyRef)的子类
- Nothing,是所有数据类型的子类,主要用在一个函数没有明确返回值时使用
7 整数类型(Byte、Short、Int、Long)
| 数据类型 | 占字节数 | 描述 | | —- | —- | —- | | Byte | 1 | 8 位有符号补码整数。数值区间为 -128 到 127 | | Short | 2 | 16 位有符号补码整数。数值区间为 -32768 到 32767
Int [4] | | Int | 4 | 32 位有符号补码整数。数值区间为 -2147483648 到 2147483647 | | Long | 8 | 64 位有符号补码整数。数值区间为 -9223372036854775808 到
9223372036854775807 = 2 的(64-1)次方-1 |
object Test07_DataType {
def main(args: Array[String]): Unit = {
// 类型推断,默认Int
val a3 = 12
// 数字过大,默认Int不行,后面加L或l
val a4 = 13432532532L
// val a5: Int = 13432532532L error
// val a6 = 13432532532 error
val b1: Byte = 10
val b2: Byte = 10 + 20 // IDEA报错但能正常输出
println(b2)
val b3: Byte = (b1 + 20).toByte // 强制类型转换
// val b3: Byte = (b1 + 20) // 报错,不能正常输出
println(b3)
}
}
8 浮点类型(Float、Double)
数据类型 | 位数 | 描述 |
---|---|---|
Float | 4 | 32位,单精度浮点数 |
Double | 8 | 64位,双精度浮点数 |
Scala的浮点型常量默认Double型,声明Float常量,后面要加f或F
9 字符类型(char)
10 布尔类型(Boolean)
Boolean类型数据只允许取值true和false,占一个字节
11 Unit类型、Null类型和Nothing类型
数据类型 | 描述 |
---|---|
Unit | 表示无值(void),用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成() |
Null | Null类型只有一个实例值null |
Nothing | 任何其他类型的子类型,当没有正常的返回值,可以用Nothing指定返回类型,可以把返回的值(异常)赋给其它的函数或者变量(兼容性) |
object Test07_DataType {
def main(args: Array[String]): Unit = {
// 空类型
// 1. 空值Unit
def m1(): Unit = {
println("m1被调用执行")
}
val a = m1() // a的类型是Unit
println(a)
}
}
object Test07_DataType {
def main(args: Array[String]): Unit = {
// 空类型
// 2. 空引用Null
// val n: Int = null // error,值类型不能接收空引用
var student = new Student("aa", 20)
student = null
println(student)
}
}
object Test07_DataType {
def main(args: Array[String]): Unit = {
// 空类型
// 3. Nothing
def m2(n: Int): Nothing = {
throw new NullPointerException
}
def m3(n: Int): Int = { // Int是Int和Nothing的公共父类
if (n == 0)
throw new NullPointerException
else
return n
}
val b: Int = m3(2)
println(b) // 2
}
}
12 类型转换
12.1 自动类型转换
精度小的类型自动转换为精度大的数据类型,数据类型按精度大小排序为:
- 自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算
- 把精度大的数值类型赋值给精度小的数值类型时,会报错
- (byte,short)和char之间不会相互自动转换
byte,short,char三者可以计算,计算时首先转换为int类型
12.2 强制类型转换
自动类型转换的逆过程,将精度大的数值类型转换为精度小的数值类型
object Test07_DataType { def main(args: Array[String]): Unit = { val n1: Int = 2.5.toInt println("n1:" + n1) // n1:2 val n2: Int = -2.9.toInt println("n2: " + n2) // n2: -2 只是取整数部分 // 强转符号只针对最近的操作数有效,会使用小括号提升优先级 val n3: Int = 2.6.toInt + 3.7.toInt println("n3: " + n3) // 5 // 小括号提升优先级 val n4: Int = (2.6 + 3.7).toInt println("n4: " + n4) // 6 } }
溢出
object Test07_DataType { /* 130: Int类型,占据4个字节,32位 原码 0000 0000 0000 0000 0000 0000 1000 0010 补码 0000 0000 0000 0000 0000 0000 1000 0010 toByte,截取最后一个字节 得到补码 1000 0010 对应原码 1111 1110 -126 */ def main(args: Array[String]): Unit = { val n: Int = 130 val b: Byte = n.toByte println(b) // -126 } }
12.3 数值类型和String类型间转换
object Test07_DataType { def main(args: Array[String]): Unit = { // 1. 数值转String val n: Int = 27 val s: String = n + "" println(s) // 27 // 2. String转数值 val m: Int = "12".toInt val f: Float = "12.33".toFloat val f2: Int = "12.3".toDouble.toInt println(f2) // 12 } }