Scala 基础

1. Scala demo

Scala 环境配置参考:Scala 初识+环境搭建

Scala 的执行模式:

  • 交互模式
  • 脚本模式

1.1 交互模式

在 CMD 中,通过 scala 目录进入 scala 环境:

image-20211130085235252

1.2 脚本模式

scala 的源文件以 .scala 结尾,编写一个源文件 Hello.scala,并在命令行中执行:

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello World!")
  }
}

image-20211130085752165

2. Scala 基础

2.1 数据类型

Scala 具有与 Java 相同的数据类型,并且具有相同的内存占用和精度。

数据类型描述
Byte8位有符号补码整数。数值区间为 -128 到 127
Short16位有符号补码整数。数值区间为 -32768 到 32767
Int32位有符号补码整数。数值区间为 -2147483648 到 2147483647
Long64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807
Float32 位, IEEE 754 标准的单精度浮点数
Double64 位 IEEE 754 标准的双精度浮点数
Char16位无符号Unicode字符, 区间值为 U+0000 到 U+FFFF
String字符序列
Booleantrue或false
Unit表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()。
Nullnull 或空引用
NothingNothing类型在Scala的类层级的最底端;它是任何其他类型的子类型。
AnyAny是所有其他类的超类
AnyRefAnyRef类是Scala里所有引用类(reference class)的基类

2.2 常量

常量: 通过 val 关键字定义常量,常量不能被重新赋值,常量的类型可以被推断,也可以显式的声明类型。

语法格式:val 变量名 [: 类型] = 变量值

1、 当常量用于表达式结果命名时,执行表达式后再引用该常量,不会再次计算

为表达式结果命名:

// 定义常量
scala> val x = 1 + 1
x: Int = 2	// 2

scala> x = 3
error: reassignment to val	// 编译失败,不能重新赋值

2、 声明类型

// 自动推断类型
scala> val x = 1 + 1
x: Int = 2

// 显示声明类型
scala> val x: Int = 1 + 1
x: Int = 2

⚠️ Scala中建议默认使用val修饰,变量,除非有需要重新赋值的场景否则 val 更为安全。

2.3 变量

变量: 通过 var 关键字定义变量,变量可以被重新赋值,变量的类型可以被推断,也可以显式声明类型。

语法格式:var 变量名 [: 类型] = 变量值

// 定义变量
scala> var y = 1 + 1
y: Int = 2

// 重新赋值
scala> y = 3
y: Int = 3

// 显示声明类型
scala> val x: Int = 1 + 1
x: Int = 2

⚠️

2.4 表达式

表达式(Expression): 可计算的语句,scala中每一行语句就是一个表达式,scala中表达式末尾不需要写 ;

scala> 1 + 1
res0: Int = 2

scala> "Hello " + "World! "
res1: String = "Hello World! "

🌈 res0res1 是表达式自动创建的变量名称,用于指代表达式的计算结果。

⚠️ 如果将两行表达式写到同一行,则必须写 ;

2.5 代码块

代码块(Blocks): 将几条表达式组合起来,并用 { } 包装为一个整体,可称为代码块。

代码块的结果: 代码块中最后一个表达式的结果

println({
  val x = 1 + 1
  x + 1
})
// 输出: 3
val res = {
    var i = 3
    println(i)
}

println(res);	// 输出: 3  ()

🌈 println 是个方法,其返回值为 Unit 类型,所以返回值为 ()

val res = {
  var i = 3
  println(i)
  "abc"
  123
  4.5
}

println(res);	//  输出: 3  4.5

2.6 方法

方法(Method): 方法由def关键字定义,def后面跟着一个方法名、参数列表、返回类型和方法体。

在面向对象的编程语言中,方法声明在类内,用来表示一些列对象的行为。

Scala 方法与 Java 方法的区别:

语言方法
Java返回值类型 方法名 (参数类型 参数名) {方法体}
void main (String[] args) {}
Scala方法名 (参数名: 参数类型 ) : 返回值类型 = {方法体}
def main (args: Array[String]): Unit = {}

实例:

def sum (a: Int, b: Int): Int ={
  a + b
}

val res = sum(1, 2)
println(res)	// 输出: 3

2.6.1 方法的参数

方法的参数设置默认值:

// 传递第二个参数
def sum (a: Int, b: Int = 2): Int ={
  a + b
}

val res = sum(1, 3)
println(res)	// 输出: 4

// 不传递第二个参数
def sum (a: Int, b: Int = 2): Int ={
  a + b
}

val res = sum(1)
println(res)	// 输出: 3

带名传参:

def sum (a: Int, b: Int = 2): Int ={
  a + b
}

val res = sum(a = 3, b = 4)
println(res)	// 输出: 7

**可变长度参数: **Scala中与Java类似的也提供了可变长度参数,每个方法只能包含一个可变长度参数,可变长度参数需要声明在参数列表末尾。

def sum2(num: Int*): Int = {
  num.sum
}

val res2 = sum2(1,2,3)
println(res2)	// 输出: 6

⚠️ sum 方法:def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus)

2.6.2 方法的返回值

Unit: Scala 中如果方法的参数列表与方法体之间不写 =,则默认使用 :Unit 补全,Unit是用来弥补Java之类的编程语言中void无法用面向对象解释的缺陷。

Unit是一个类 这个类只有一个实例 (), 用来表示不需要返回值的方法的返回值类型。

def sum3(a: Int, b: Int){
  a + b
}

val res3 = sum3(1, 2)
println(res3)	// 输出: ()

需要返回值: 如果方法需要返回值 可以加上 =,Scala会根据方法体的最后一行表达式的值 推断返回值类型。

def sum4(a: Int, b: Int) = {
  a + b
  "aaa"
  1.4
}

val res4 = sum4(1, 2)
println(res4)	// 输出: 1.4

image-20211130105248031

return: Scala中如果希望方法体的最后一行作为返回值,省略return关键字不写,如果使用return关键字 必须明确声明返回值类型。

def sum5(a: Int, b: Int): Int = {
  return a + b
}

val res5 = sum5(1, 2)
println(res5)	// 输出: 3

2.7 函数

函数(Function): 带有参数的表达式,默认使用 def 声明。

语法格式:

def 函数名(函数参数:参数类型):返回值类型={
    函数体
}

函数和方法的区别:

  • 方法method 声明在类中(直接属于类),用来描述对象的行为
  • 函数function 可以声明在任何位置,函数就是参数和返回值的映射关系

实例:

object Scala_Funciton {

    // 方法,直接属于对象
    def m1: Unit ={
        // 函数
        def m2: Unit ={
            // 函数
            def m3: Unit ={

            }
        }
    }
}

2.7.1 声明函数

当函数体只有一行时,可以写在一行,并省略 {},能够自动化推断返回值类型。

def main(args: Array[String]): Unit = {
  def add(a: Int) = a + 1
}

2.7.2 匿名函数

// 是一个  Int=>Int 类型的函数
(a: Int) => a + 1
//  输入参数类型     输出参数类型
    Int         => Int
//  变量名  变量类型      对应类型的实例
val f1:    Int => Int = (a: Int) => a + 1	// 函数类型
val i:     Int        = 123
val s:     String     = "abc"

2.7.3 高阶函数

函数可以作为其他函数的参数

/**
     * @param op 函数类型
     * @return Int 类型
     */
def calc(i: Int, j: Int, op: (Int, Int) => Int) = {
    op(i, j)
}

// 函数调用
// 第三个参数,传递一个函数
val calc_res = calc(1, 2, (a: Int, b: Int) => a + b)
println(calc_res)	// 返回: 3

1、匿名函数 f 作为其他函数的参数时 f 的参数类型可以省略

val calc_res2 = calc(1, 2, (a, b) => a + b)
println(calc_res2)	// 返回: 3

2、二元匿名函数f 作为其他函数的参数时,如果f的参数声明循序和调用顺序一致 并且f的每个参数都只使用了一次,可以用 _ 代替

val calc_res3 = calc(1, 2, _+_)
println(calc_res3)	// 返回: 3

函数可以作为其他函数的返回值

2.8 类

类: Scala中可以使用class关键字声明类,class仅仅是对象的模板,对象的抽象,类不能直接调用属性和方法。

案例:

object Scala_Class {

    def main(args: Array[String]): Unit = {
        
        // 可以使用new关键字 调用类的构造器 用于创建类的实例
        val student = new Student()

        // 对象可以调用自己的属性和方法
        student.name
        student.age
        
    }
}

class Student() {
    
    val name: String = "JOEL"
    var age: Int = 123
    
}

构造器: Scala中类的声明就是主构造器,主构造器的参数如果使用 val 或者 var 修饰,直接作为类的成员属性。

object Scala_Class {

  def main(args: Array[String]): Unit = {
    val student = new Student("JOEL", 123)
    student.name
    student.age
  }
}

class Student(val name: String, var age: Int) {

}

辅助构造器: Scala还允许给类添加辅助构造器,辅助构造器是一些使用 def 声明的方法,方法名叫 this, 辅助构造器需要直接或者间接的调用主构造器。

object Scala_Class {

  def main(args: Array[String]): Unit = {
    // 主构造器
    val student1 = new Student("JOEL", 123)
    // 一个参数的构造器
    val student2 = new Student("JOEL")
    // 无参构造器
    val student3 = new Student()
  }
}

// 相当于主构造器
class Student(val name: String, var age: Int) {

  // 一个参数的构造器
  def this(name: String) {
    this(name, 123)
  }

  // 空参构造器
  def this(){
    this("未知")
  }
}

2.9 对象

对象(Object):scala中添加了object关键字用于创建单例对象。

2.9.1 伴生

伴生: 如果在同一个Scala源代码文件中,出现名称完全相同的class和object,此时 类和对象互为伴生关系

  • 类叫做对象的伴生类
  • 对象叫做类的伴生对象

伴生对象和伴生类可以互相访问私有成员

由于object 中的成员可以直接被对象名调用,所以通常将类中类似 Java static 修饰的成员(公用的)封装在类的伴生对象中,而 class 中仅仅声明每个对象个性化的成员

// 类
class Persion {

  // 声明类的属性时,可以使用 _ 代表对应类型的默认值
  var name: String = _  // 默认为 Null
  var age: Int = _  // 默认为 0
}

// 对象
object Persion{
  def m1: Unit ={
    println("Persion类的方法")
  }
}

2.9.2 对象

对象: scala中添加了object关键字用于创建单例对象

案例:

object Scala_Object {

  def main(args: Array[String]): Unit = {

    Gamer.playLOL()

    val person = new Person
    person.name
    person.age
    
  }
}

object Gamer {
  def playGame(): Unit = {
    println("打的贼菜")
  }
}

Java 调用 Scala 定义的对象

public class Test {
    public static void main(String[] args) {
        Person person = new Person();
        // 相当于 get()
        String name = person.name();
        int age = person.age();
        //相当于 set()
        person.name_$eq("JOEL");
        person.age_$eq(123);
    }
}

如果在 Scala 中定义的对象,可以通过添加注解的方式,来显示的调用 get、set 方法。

import scala.beans.BeanProperty

class Person {
    
  @BeanProperty
  var name: String = _
  @BeanProperty
  var age: Int = _
}

image-20211130123309199

image-20211130123358052

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JOEL-T99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值