美文网首页
Scala 基础

Scala 基础

作者: 马本不想再等了 | 来源:发表于2019-10-08 13:00 被阅读0次

    1. Scala 与 Java 的关系

    Scala 和 Java 都是运行在 JVM 上。
    Scala 可以调用 Java 的类库,在语法上较 Java 更为简洁
    Scala 将函数式编程和面向对象思想完美的结合

    2. 基本语法

    class Hello {
      /*
      定义变量: val 代表常量;var 代表变量
      val/var 变量名:变量类型 = 变量值
      */
      val a: Int = 1
      /*
      定义方法:
      def 函数名(参数名:参数类型):返回值类型={方法体}
      */
      def hello(arg: String): Unit = {
        println(arg)
      }
    }
    object Hello {
      // Scala程序的入口
      def main(args: Array[String]): Unit = {
        println("hello,scala")
      }
      /*
      完全面向对象:scala 完全面向对象,故 scala 去掉了 java 中非面向对象的元素,如 static 关键字,void 类型
      1.static
      scala 无 static 关键字,由 object 实现类似静态方法的功能(类名.方法名),object 关键字和 class 的关键字定义方式相同,但作用不同。class 关键字和 java 中的 class 关键字作用相同,用来定义一个类;object 的作用是<front color:green>声明一个单例对象<front color>,object 后的“类名”可以理解为该单例对象的变量名。
      2.void
      对于无返回值的函数,scala 定义其返回值类型为 Unit 类,Unit 只有一个 Null 对象。
      */
    }
    

    3. 运行原理

    1. object 在底层会生成两个类 Hello , Hello$
    2. Hello 中有个 main 函数,调用 Hello$ 类的一个静态对象 MODULES$
    3. Hello$.MODULES$.对象 是静态的,通过该对象调用 Hello$ 的 main 函数
    4. 在 main 中写的代码在放在 Hello$ 的 mian 中,Scala 编译器在底层做了包装
    5. Scala 程序的执行入口时 object 中的 mian() 函数
    /* Hello 源代码 */
    object Hello {
    def main(args: Array[String]): Unit = {
              //4. 可以理解我们在 main 中写的代码在放在 Hello$ 的 main,在底层执行 scala 编译器做了一个包装
            println("hello,scala")
        }
    }
    //1. object 在底层会生成两个类 Hello , Hello$
    /* Hello.class 类 */
    //2. Hello 中有个 main 函数,调用 Hello$ 类的一个静态对象 MODULES$
    public final class Hello
    {
        public static void main(String[] paramArrayOfString)
        {
            Hello$.MODULE$.main(paramArrayOfString);
        }
    }
    /* Hello$.class 类 */
    public final class Hello$
    {
        public static final  MODULE$;
        static { new (); }
        public void main(String[] args)
        {
              //3. Hello$.MODULE$. 对象是静态的,通过该对象调用 Hello$ 的 main 函数
              Predef..MODULE$.println("hello,scala");
        }
        private Hello$()
        {
              MODULE$ = this;
        }
    }
    

    说明:

    1. Scala 中如果使用 object 关键字声明类,在编译时会同时生成两个类:当前类当前类$
    2. 使用 当前类$ 的目的在于模拟静态语法,可以通过类名直接访问方法。
    3. Scala 将 当前类$ 这个对象称之为“伴生对象”,伴随着类所产生的对象,这个对象中的方法可以直接使用。
      总结:object 对象名 中的 mian() 方法就是 对象名$ 中的 MODULES$ 的 mian()

    4. 字符串输出

    4.1 格式化输出 printf

    字符串,通过 % 传值。

    val a = 10
    // 格式化输出
    printf("a的值是: %d %.2f %s", a, 2.888, "abc")
    a的值是: 10 2.89 asc
    

    4.2 模板输出

    三重引号中间可以使用模板输出,方便多行带缩进的代码,方便 SQL

    val s =
    """
      |select
      |   name,
      |   age,
      |   gender
      |from user
      |where name='zhangsan';
    """.stripMargin
    print(s)
    

    4.3 字符串变量赋值输出

    可以使用 ${变量} 的形式传值,{ } 内也可以进行计算

    val name = "zhangsan"
    val age = 20
    val b =
      s"""
         |select
         |   name,
         |   age,
         |   gender
         |from user
         |where name='${name}' and age=${age + 2};
      """.stripMargin
    println(b)
    

    5. 键盘输入

    三种常用的输入,Stdln.readLine、Stdln.readShort、Stdln.readDouble

    //1. 输入姓名
    val name = StdIn.readLine("请输入姓名")
    //2. 输入年龄
    print("请输入年龄:")
    val age = StdIn.readShort()
    //3. 输入薪水
    print("请输入薪水:")
    val salary = StdIn.readDouble()
    

    6.数据类型

    基本数据类型

    image.png
    1. Scala 中一切数据都是对象,都是 Any 的子类
    2. Scala 中数据类型分为两大类:数值类型(AnyVal)、引用类型(AnyRef),这两种类型都是对象
    3. Scala 数据类型遵循低精度向高精度自动转换(隐式转换)
    4. Scala 特殊的类型之 Null,它只有一个实例就是 null,它是所有引用类型的(AnyRef) 的子类
    5. Boolean:true / false
    6. Unit 类型:无值,和 java 中 void 等同。用作不返回任何结果的方法的结果类型。Unit 只有一个实例值,写成 ()
    7. ​StringOps 类型:对 Java 中 String 类型的扩展
    8. Nothing 类型:Nothing 类型在 Scala 的类层级的最低端;它是任何其他类型的子类型。当一个函数,我们确定没有正常的返回值,可以用 Nothing 来指定返回类型(联想 java 的多态),这样可以把返回的值(异常)赋给其它的函数或者变量(兼容性)

    7. 类型转换

    自动类型转换

    image.png
    强制类型转换
    将精度大的数值类型转换为精度小的数值类型。使用时要加上强制转函数,但可能造成精度降低或溢出,格外要注意。
    // Char类型可以保存Int的常量值,但不能保存Int的变量值,需要强转
    var c2: Char = 98 // 正确,因为直接将一个数值给char,编译器只判断是否越界
    var c3: Char = 'a' + 1 // 错误,Int高->char低,编译器判断类型
    var c4: Char = ('a' + 1).toChar // 正确,先提升成 Int,在强转成 Cahr,输出 b
    
    // Byte和Short类型在进行运算时,当做Int类型处理。
    var a : Short = 5   
    a = a-2 // 错误, Int->Short
    var b : Byte = 3    
    b = b + 4 // 错误,Int->Byte
    

    8. 运算符

    1. 对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
    var r1: Int = 10 / 3 // 3
    println("r1=" + r1)
    
    var r2: Double = 10 / 3 // 3.0
    println("r2=" + r2)
    
    var r3: Double = 10.0 / 3 // 3.3333
    println("r3=" + r3)
    println("r3=" + r3.formatted("%.2f"))   // 保留小数点2位,使用四舍五入
    
    1. 在做比较时 == 的作用和 java 中的 .equals() 方法类似,而 = 则更多的是使用 .eq 来操作
    2. Scala 中没有++、--操作符,需要通过 +=、-= 来实现同样的效果
    3. 本质上 Scala 中没有任何的运算符,因为所有的运算符都是函数

    9. 流程控制

    9.1 if else

    if else 语句和 java 类似,但是,Scala 中 if else 是有返回值的,返回值取决于满足条件的代码体的最后一行内容。
    Scala 没有 switch case 结构,有一种更强大的结构(模式匹配)。

    9.2 for 遍历

    // 1.前闭后闭,i 从1循环到3
    for(i <- 1 to 3){
        print(i + " ")
    }
    1 2 3
    
    // 2.前闭后开,i 从1循环到2
    for(i <- 1 until 3){
        print(i + " ")
    }
    1 2
    
    // 3.循环守卫,加入条件 if i != 3,当i不等于3时满足条件,即输出时跳过3,类似于 java 中的 continue
    for (i <- 1 until 10 if i != 3) {
        print (i + " ")
    }
    1 2 4 5 6 7 8 9
    
    // 4.循环步长,by 表示步长
    for (i <- 1 to 10 by 2) {
      print(i +" ")
    }
    1 3 5 7 9
    
    // 5.嵌套循环,注意此处没有关键字,所以范围后要加;来隔断逻辑
    // 注意:只有当所有的逻辑在内循环中,才可以将两个循环成一个for
    for (i <- 1 to 2; j <- 1 to 3) {
      println("i=" + i + "j=" + j)
    }
    i=1j=1
    i=1j=2
    i=1j=3
    i=2j=1
    i=2j=2
    i=2j=3
    
    // 6.引入变量
    // 引入变量
    for (i <- 1 to 3; j = 4 - i) {
      println("i=" + i + "j=" + j)
    }
    i=1j=3
    i=2j=2
    i=3j=1
    
    // 7.循环返回值,将循环中的所有值*2,并将结果返回到新的集合中
    val res = for(i <- 1 to 10) yield {
      i * 2
    }
    println(res)
    

    9.3 While 循环

    while 语句没有返回值,即整个 while 语句的结果是 Unit 类型 ()

    // while 循环与 java 中类似
    var i = 0
    while (i < 10) {
      println(i+" ")
      i += 1
    }
    

    注:因为 while 中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量,而变量需要声明在 while 循环的外部,那么就等同于循环的内部对外部的变量造成了影响,也就违背了函数式编程的重要思想(输入=>函数=>输出,不对外界造成影响),所以不推荐使用,而是 推荐使用 for 循环

    9.4 循环终止

    Scala 为更好的适应函数式编程,使用 breakable() 方法和 break() 方法控制结构来实现 break 和 continue 功能。
    Scala 的循环终止,本质上是用抛异常的并捕获异常的方式 解决的,分别用 break() 方法抛异常,用 breakable() 方法捕获

    import util.control.Breaks._
    // 实现 break 功能
    var i = 0
    breakable {
      while (i < 10) {
        println("i=" + i)
        i += 1
        if (i == 5) break()
      }
    }
    
    // 实现 continue 功能
    var j = 0
    while (j < 10) {
      breakable {
        j += 1
        if (j == 5) break()
        println("j=" + j)
      }
    }
    

    注:break:breakable 放在循环外;continue:breakable 放在循环内

    相关文章

      网友评论

          本文标题:Scala 基础

          本文链接:https://www.haomeiwen.com/subject/uerbpctx.html