大数据Scala学习之旅第一篇

277 阅读5分钟

「这是我参与11月更文挑战的第29天,活动详情查看:2021最后一次更文挑战」。

一、函数

1、函数柯里化 & 闭包

闭包:函数式编程的标配

  1. 说明

    闭包:如果一个函数,访问到了它的外部(局部)变量的值,那么这个函数和他所处的环境,称为闭包。

    函数柯里化:把一个参数列表的多个参数,变成多个参数列表。

  2. 案例实操

    • 闭包

          def f1() = {
            var a: Int = 10
      
            def f2(b: Int) = {
              a + b
            }
      
            f2 _
          }
      
          // 在调用时,f1 函数执行完毕后,局部变量 a 应该随着栈空间释放掉
          val f = f1()
          // 但是在此处,变量 a 其实并没有释放,而是包含在了 f2 函数的内部,形成了闭合的效果
          println(f(3))
          println(f1()(3))
      
    • 函数柯里化

          // 函数柯里化,其实就是将复杂的参数逻辑变得简单化,函数柯里化一定存在闭包
          def f3()(b: Int) = {
            1 + b
          }
      
          println(f3()(3))
      

2、递归

  1. 说明

    一个函数/方法在函数/方法体内又调用了本身,我们称之为递归调用

  2. 案例实操

     def main(args: Array[String]): Unit = {
         // 阶乘
         // 递归算法
         // 1) 方法调用自身
         // 2) 方法必须要有跳出的逻辑
         // 3) 方法调用自身时,传递的参数应该有规律
         // 4) scala 中的递归必须声明函数返回值类型
         println(test(5))
     }
     
     def test(i : Int) : Int = {
         if (i == 1) {
             1
         } else {
             i * test(I - 1)
         }
     }

3、控制抽象

  1. 值调用

    把计算后的值传递过去

      def main(args: Array[String]): Unit = {
        def f = () => {
          println("f...")
          10
        }
    
        foo(f())
      }
    
      def foo(a: Int): Unit = {
        println(a)
      }
    
  2. 名调用

    传名参数,传递的不再是具体的值,而是代码块

    def f2(a: =>Int): Unit = {
      println("a: " + a)
      println("a: " + a)
    }
    
    f2(23)
    f2(f1())
    
    f2({
      println("这是一个代码块")
      29
    })
    

4、惰性加载

  1. 说明

    当函数返回值被声明为 lazy 时,函数的执行将被推迟,直到我们首次对此取值,该函数才会执行。这种函数我们称之为惰性函数。

  2. 案例实操

    def main(args: Array[String]): Unit = {
     lazy val res = sum(10, 30)
     println("----------------")
     println("res=" + res)
    }
    def sum(n1: Int, n2: Int): Int = {
     println("sum 被执行。。。")
     return n1 + n2
    }
    

    注意:lazy 不能修饰 var 类型的变量

二、面向对象

Scala 的面向对象思想和 Java 的面向对象思想和概念是一致的。

Scala 中语法和 Java 不同,补充了更多的功能。

1、Scala 包

  1. 基本语法

    package 包名

  2. Scala 包的三大作用(和 Java 一样)

    区分相同名字的类

    当类很多时,可以很好的管理类

    控制访问范围

1.1、包的命名

  1. 命名规则

    只能包含数字、字母、下划线、小圆点.,但不能用数字开头,也不要使用关键字。

  2. 案例实操

    demo.class.exec1 //错误,因为 class 关键字
    
    demo.12a //错误,数字开头
    
  3. 命名规范

    一般是小写字母+小圆点

    com.公司名.项目名.业务模块名

  4. 案例实操

    com.moe.oa.model
    
    com.moe.oa.controller
    
    com.sohu.bank.order
    

1.2、包说明(包语句)

  1. 说明

    Scala 有两种包的管理风格,一种方式和 Java 的包管理风格相同,每个源文件一个包(包名和源文件所在路径不要求必须一致),包名用“.”进行分隔以表示包的层级关系,如com.moe.scala。另一种风格,通过嵌套的风格表示层级关系,如下:

    package com{
    
        package moe{
    
        package scala{
    
        }
    
        }
    
    }
    

    第二种风格有以下特点:

    一个源文件中可以声明多个 package

    子包中的类可以直接访问父包中的内容,而无需导包

  2. 案例实操

    package com {
     import com.moe.Inner //父包访问子包需要导包
     object Outer {
            val out: String = "out"
             def main(args: Array[String]): Unit = {
                    println(Inner.in)
             }
     }
     package moe {
             object Inner {
                    val in: String = "in"
                    def main(args: Array[String]): Unit = {
                            println(Outer.out) //子包访问父包无需导包
                    }
             }
     }
    }
    
    package other {
    
    }
    

1.3、包对象

在 Scala 中可以为每个包定义一个同名的包对象,定义在包对象中的成员,作为其对应包下所有 class 和 object 的共享变量,可以被直接访问。

  1. 定义

    package object com{
    
    val shareValue="share"
    
    def shareMethod()={}
    
    }
    
  2. 说明

    • 若使用 Java 的包管理风格,则包对象一般定义在其对应包下的 package.scala文件中,包对象名与包名保持一致。
    • 如采用嵌套方式管理包,则包对象可与包定义在同一文件中,但是要保证包对象与包声明在同一作用域中。

1.4、导包说明

  • 和 Java 一样,可以在顶部使用 import 导入,在这个文件中的所有类都可以使用。
  • 局部导入:什么时候使用,什么时候导入。在其作用范围内都可以使用
  • 通配符导入:import java.util._
  • 给类起名:import java.util.{ArrayList=>JL}
  • 导入相同包的多个类:import java.util.{HashSet, ArrayList}
  • 屏蔽类:import java.util.{ArrayList =>,}
  • 导入包的绝对路径:new root.java.util.HashMap

2、类和对象

类:可以看成一个模板

对象:表示具体的事物

2.1、定义类

  1. 回顾:Java 中的类

    如果类是 public 的,则必须和文件名一致。

    一般,一个.java 有一个 public 类

    注意:Scala 中没有 public,一个.scala 中可以写多个类。

  2. 基本语法

    [修饰符] class 类名 {

    类体

    }

    说明

    • Scala 语法中,类并不声明为 public,所有这些类都具有公有可见性(即默认就是public)
    • 一个 Scala 源文件可以包含多个类
  3. 案例实操

    package com.moe.chapter06
    
    //(1)Scala 语法中,类并不声明为 public,所有这些类都具有公有可见性(即默认就是 public)
    class Person {
    }
    //(2)一个 Scala 源文件可以包含多个类
    class Teacher{
    }
    

2.2、属性

属性是类的一个组成部分