学习链接:https://www.bilibili.com/video/BV1Xh411S7bP?p=13&spm_id_from=333.1007.top_right_bar_window_history.content.click


1 变量和常量

声明变量时,类型可以省略,编译器自动推导,即类型推导
类型确定后,就不能修改,Scala是强数据类型语言
声明时,必须要有初始值
在声明/定义一个变量时,可以使用var或者val来修饰,var修饰的变量可改变,val修饰的变量不可改
var修饰的对象引用可以改变,val修饰的对象不可改变,但对象的状态(值)确是可以改变的

1.1 变量

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

  1. var i: Int = 10
  2. var a = 10

1.2 常量

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

val j: Int = 20
val b = 15

能用常量的地方不用变量

  • 类型确定了就不能更改

QQ截图20220524101128.png

  • val修饰的对象不可改变

QQ截图20220524102002.png
但对象的状态可以改变

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 标识符

  1. 命名规则

    1. 以字母或者下划线开头,后接字母、数字、下划线
    2. 以操作符开头,且只包含操作符(+- * / # !)等 如:val ++++ = 10
    3. 用反引号...包括的任意字符串,即使是Scala关键字也可以 val class = 111
      package, 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 字符串输出

      基本语法:
  2. 字符串,通过+连接

  3. printf用法:字符串,通过%传值
  4. 字符串模板(插值字符串):通过$获取变量值

    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)
    }
    }
    

    QQ截图20220524113611.png

    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)
  }
}
  1. 将数据写入文件
    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()
    }
    }
    
    QQ截图20220524115205.png

    6 数据类型

    QQ截图20220524183847.png
  • 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)

字符类型可以表示单个字符,字符类型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)
  }
}

QQ截图20220525104142.png

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)
  }
}

QQ截图20220525104612.png

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 自动类型转换

精度小的类型自动转换为精度大的数据类型,数据类型按精度大小排序为:
尚硅谷大数据技术之Scala.jpg

  • 自动提升原则:有多种类型的数据混合运算时,系统首先自动将所有数据转换成精度大的那种数据类型,然后再进行计算
  • 把精度大的数值类型赋值给精度小的数值类型时,会报错
  • (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
    }
    }