• Scala编程基础


    Scala编程基础

    Scala之父——马丁.奥德斯基

    Scala将面向对象编程函数式编程和强大的类型系统结合起来,让人能写出优雅、简洁的代码。

    表达式、语句和代码块与Java一样,还有类、包和引用的语法。除语法之外,Scala还采用了Java的其他元素,如它的基本类型、类库和它的执行模式。函数式编程借鉴了SML,OCaml,和F#为代表的ML家族语言很接近,Scala的隐式参数灵感来自Haskell,基于actor的并发库来自EeLang的思想。

    Scala特点

    面向对象:Scala中的每一个值都是一个对象,包括基本数据类型在内,连函数也是对象。

    函数式编程:Scala是一种函数式语言,函数也能当成值来使用。Scala提供了轻量级的语法以定义匿名函数,支持高阶函数,允许嵌套多次函数,并支持柯里化。Scala的case class(样例类)及其内置的模式匹配相当于函数式编程语言中常用的代数类型。

    静态类型:Scala具备类型系统。
    类型系统支持以下特性:

    • 泛型类
    • 协变和逆变
    • 标注
    • 类型参数的上下限约束
    • 把类型和抽象类型作为对象成员
    • 复合类型
    • 引用自己时显示指定类型
    • 视图
    • 多态方法

    扩展性:Scala提供了许多独特的语言机制,可以以库的形式轻易无缝添加新的语言结构:

    • 任何方法可用作前缀或后缀操作符
    • 可以根据预期类型自动构造闭包

    动态性:Scala使用Actor作为其并发模型,Actor是类似线程的实体,通过邮箱收发消息。Actor可以复用线程,因此可以在程序中可以使用数百万个Actor,而线程只能创建数千个。在2.10之后的版本中,使用Akka作为其默认Actor实现。

    函数式编程

    函数式编程是一种“编程范式”

    函数式编程的特点
    • 函数是⼀等公民:指的是函数与其他数据类型⼀样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。
    • 以表达式为中心
    • 无副作用:⼀个函数在程序执行过程中除了根据输⼊参数给出运算结果外,没有其他的影响,就称为没有副作用的。
    • 不修改状态:状态不能保存在变量中
    • 引用透明:不依赖外部变量或状态
    函数式编程的优势
    • 代码简洁
    • 接近自然语言
    • 易于代码管理
    • 适合并发编程
    • 适用于热升级

    函数式编程的一个特点是,函数也是值,同允许把函数本身作为参数传入另一函数,还允许返回一个函数!

    静态、动态语言

    静态编程语言:实现声明变量类型,类型不能改变,编译时检查

    动态编程语言:不用事先声明类型,随时可以赋值为其他类型,编程时不知道什么类型,很难推断

    强、弱类型语言

    强类型语言:不同类型之间操作,必须强制类型转换为同⼀类型

    弱类型语言:不同类型间可以操作,自动隐式转换

    Scala解释器

    Scala解释器也被称为REPL交互式编码环境

    REPL:Read(取值)-> Evaluation(求值)-> Print(打印)-> Loop(循环)。

    符号$在Scala中可以看作字母,避免使用$开始的标识符,以免造成冲突。

    变量与类型

    val修饰的变量,相当于Java中final修饰的变量;

    val s1 = "1"//定义常量s1,使⽤字符串"1"赋值,⾃动推断为String类型,值不可变
    val s2:String = "2"//定义常量s2,⼿动指定类型为String,此时需要保证所赋值类型匹配
    //使⽤val定义基本数据类型时,值不可变,可以使⽤val重新定义
    
    • 1
    • 2
    • 3

    变量声明一定要初始化

    变量推断

    含义:声明变量时,可以不指定变量类型,编译器会根据赋值内容自动推断当前变量的类型。

    var i1 = 1
    print(i1.isInstanceOf[Int])//定义变量a1,使⽤1赋值,⾃动推断为Int类型
    i1 = 1.1类型确定后,就不能再赋值的类型
    
    • 1
    • 2
    • 3
    多变量定义
    val(a,b,c) = (1,2,"a")//Scala中的多个变量的初始化
    var i3,i4 = 10;//定义变量i3,i4,同时赋值为10
    
    • 1
    • 2
    var和val的区别
    是否可变

    使用val声明⼀个常量或值:val修饰的变量是不可变的,注意不可变的是引用,而不是内容 ,val修饰的变量在编译后,等同于加上final。

    使用var 声明⼀个变量:var修饰的变量,内容和引用都可变

    是否可以有lazy修饰:延迟加载

    只有val修饰的变量才能被lazy修饰,使用lazy定义变量后,只有在调用该变量时才会实例化这个变量的值,类似方法,先声明,后调用。

    scala> val a = 10
    a: Int = 10
    scala> lazy val b = 100
    b: Int = <lazy>
    scala> b
    res2: Int = 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用val OR var?

    官方推荐val,使用val的好处:

    • 更安全
    • 代码可读性高
    • 资源回收更快,方法执行完,val所定义的变量即回收
    类型层级关系

    在这里插入图片描述

    Any:所有类型的父类

    它定义了⼀些通用的方法如equals、hashCode和toString。Any有两个直接子类:AnyVal和AnyRef。

    AnyVal:所有值类型的父类

    有9个预定义的非空的值类型分别是:Double、Float、Long、Int、Short、Byte、Char、Unit和Boolean。Unit是不带任何意义的值类型,它仅有⼀个实例可以像这样声明:(),和Java不同的是 ,Scala没有基本类型与包装类型之分,这些类型都是类,有自己的属性和方法。

    AnyRef:所有引用类型的父类

    AnyRef代表引用类型。所有非值类型都被定义为引用类型。包括List、String以及自定义类等。

    Nothing:所有类型的子类

    常见的应用如:抛出异常、程序exit,无限循环等,返回值为Nothing类型。

    Nothing没有对象,但是可以用来定义类型。

    类型转换

    自动类型转换

    在这里插入图片描述

          //自动类型转换属于Scala中隐式转换
          val b:Byte = 10;
          val s:Short = b;
          val i:Int = s;
          val l:Long = i;
          //Scala中允许将小数据类型范围数据赋值给大范围数据类型变量存储
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    当Char转整型时:

     //当Char类型转换为整数时需要注意:
          val b1:Byte = 'a'; //英文字母是1个字节
          /*
          Error:(11, 21) type mismatch; found   : Char('我')
           required: Byte  val b2:Byte = '我';
           中文是2个字节所以无法存在Byte中
           */
          //val b2:Byte = '我';
          //提供大于等于2个字节数据类型是可以存的
          var s1:Short = '我'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    小结:

    低位数可以向高位数数转换。如Byte->Short

    字符可以转整形或浮点型,不同长度字符应使用不同位数的整型

    整型可以转浮点型,允许精度丢失。如Long->Float

    强制类型转换

     //Scala中提供一个 toXXX 的方法 XXX就是值类型 就可以完成强制类型转换
         var i1:Int = 10;
         var b3:Byte = i1.toByte;
         b3.isInstanceOf[Byte] //检查b3是否属于Byte类型【得到结果true/false】
         var d:Double = 19.9;
         var i2:Int = d.asInstanceOf[Int]; //相当于d强制类型转换为int类型存储在i2变量中
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    数值类型和字符串类型的转换

    数值类型转换为字符串类型

    //将1.23和1转换为字符串类型
    val str1 = 1.23+"";
    val srr2 = 1.toString;
    
    • 1
    • 2
    • 3

    字符串类型转数值类型

    val d2 = str1.toDouble
    val i3 = str2.toInt
    
    • 1
    • 2

    操作符

    实际上Scala中没有操作符

    a + b 等价于 a.+(b)

    通过Int类型变量a调用了Int中提供+方法,方法参数是b求和操作

    在Scala中 + 是一个方法 所以Scala中就允许使用 数据类型对应数据进行方法调用操作

    Scala没有++,-- 可以用+=,-=代替

    操作符都是方法的重载,是方法的调用

    表达式

    表达式:一段可以被求值的代码,在Scala中一切都是表达式

    ps:Scala不会像Java一样单纯使用运算符和变量或常量组成表达式

    //表达式与语句的区别
    //Scala中的表达式与Java中的表达式共同共享一个概念【常量、变量、运算符组成】
    var sum = 1+2;//ps:是一行语句
    /*
    在Scala中一切都是表达式
    ps:提供块表达式的说明{}中提供一行或多行代码总体称之为块表达式
     */
    val bool = if(true){
        true
    }else{
        false
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    块表达式

    	//块表达式只需提供{},在{}中提供代码
    	var i = {	//最后一个表达式即为返回值,不需要使用return
          0			//等价于var i= 0 这个0是返回赋值给i这个变量
        }
        //添加return语句,除非自定义方法、函数中,使用return作为返回值使用,不建议单独使用
    //    var sum:Int ={
    //      return 1+2
    //    }
        var sum :Int ={
          1+2
        }
        //简化:var sum = 1+2
        //块表达式中可以提供一条或多条语句【一个计算逻辑,需要得到结果】
        var num1=1
        var sum1 ={
          num1 = num1+1
          num1
        }
        println("sum1="+sum1)
        /*
        等价于
        var num1 = 1
        num1= num1+1
        var sum = num1
         */
        var sum2 = {
          num1 = num1 + 1
        }
        println("sum="+sum2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    if分支条件表达式
    	/*
        scala中的分支只有if分支
        没有switch...case,Scala中提供强大的“匹配模式”
        基础应用效果就是和Java一样提供分支语句判断
         */
    	//判断是不是闰年
        val year = 2000
        if((year%4==0&&year%100!=0)||(year%400==0)){
          println("闰年")
        }else{
          println("不是闰年")
        }
        //Scala中一切皆为表达式
        val res:Boolean = if((year%4==0&&year%100!=0)||(year%400==0)) true else false
        //scala分支语句返回值特点1:
        //使用if并进行返回值接收
        val x = 1
        /*
        if 单分支语句缺少false判断结果
        通用语句-->if(判断条件)返回值else()
         */
        val res2:AnyVal = if(x>2) 1
        /*
        如果判断语句返回语句中有引用类型AnyRef和值类型AnyVal-->得到返回值类型就是Any
         */
        val res3 = if(x.isInstanceOf[Int])"11" else 0
        //scala分支语句返回值特点2:
        //使用if- else 语句或 if-else if语句,返回值类型都是一样,确定一个返回值类型
        val res4:Int = if(x>2) 1 else -1
        /*
        如果返回值不是引用数据类型【即数据类型不一致】
        如果确定与值类型有关即存在Unit-->AnyVal 如果是 引用类型和值类型-->Any
         */
        val res5:Double = if(x>2) 1 else 1.3234//不需要Anyval double就可以
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    单分支
    /*
         PS:Scala中 if分支语句不仅具有分支语句特点(选择性执行)
             而且也是Scala中表达式 即 可以得到Scala中计算结果
          */
          /*
          以Scala中if分支条件表达式来进行演示,分支语执行流程
          参考Java中分支语句即可
           */
          // if单分支
          val x = 1;
          val res = if( x > 2) 1;
          /*
          如果使用 if 单分支 作为 条件表达式计算时
          如果语句缺少为false时的结果,那么Scala会将if单分支判断看做
          if(x>2) 1 else ()
           if单分支是缺少else Scala会进行默认 不全 返回的是
           () 即Unit类型
            所以此时res的数据类型就是 AnyVal
            如果if提供返回数据是引用类型(AnyRef) 最终结果数据类型就是Any
           */
           //因为默认不全之后是Any或AnyVal类型所以建议得到数据之后进行转换操作以保证数据可以正确执行
           val res1 =  if(res.isInstanceOf[Int]) res.asInstanceOf[Int] else 0;
           println(res1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    双分支
    //当条件表达式成立,即执行代码块1,否则执行代码块2.
    //if-else 分支
        val x1 = 2;
        /*
          因为显示的补全了else操作 所以这个类型是可控
           */
        val res2 = if (x > 0) 2 else 1;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    多分支
        val x2 = 2;
        val res3 = if (x > 0) 2 else if(x >=1) 1 else 0;
    
    • 1
    • 2
    循环表达式
    for循环

    与Java中基本for循环是不一样的和foreach循环相似,Scala独有

    	//for循环
        /*
        语法:
        for(i <- 范围|集合|数组){
        ps:i这个变量就会获得 范围|集合|数组 中每一个元素进行操作
        }
         */
        //提供范围,简化为 to (包含)until(不包含)
        //根据range提供范围执行循环操作
        for(i <- Range(1,6)){
          println(i)
        }
        //如果需要精准控制循环范围 可以使用 to和until(不包含)
        for(i <- 1 to 5){
          println(i)
        }
        for(i <- 1 until 5){
          println(i)
        }
        //嵌套循环--》标准循环嵌套
        for(i <- 1 to 9){
          for(j <- 1 to i){
            print(j+"x"+i+"="+i*j+"\t")
          }
          println()
        }
        //for循环提供嵌套,写到同一个小括号使用【;】
        for(i <- 1 to 9;j <- 1 to i){
          print(j+"x"+i+"="+i*j+"\t")
        }
        //scala中允许在for循环小括号中添加“守卫” 就是添加循环判断条件
        /*
        循环守卫:循环时 可以增加条件判断来决定是否执行循环,这个判断条件就是守卫
         */
        //循环1-5之间的数据,如果当数据不为3的时候打印结果
        for(i <- 1 to 5){
          if(i!=3){
            print(i)
          }
        }
        //scala将if判断改变语句到小括号中称之为“守卫”
        for(j <- 1 to 5;if(j!=3)){
          print(j)
        }
        //yield 被称为for循环推导式 可以将for结果通过yield关键字后面提供 表达式计算 得到数组
        //ps:只有循环使用yield关键字之后 我们才会进行循环返回值的接收
        val ints = for (i <- 1 to 5) yield i * 2
        for(i <- ints){
          println(i)
        }
    
        //1 to 5 每次自增效果都是1,2,3,4,5 控制增长 步长
        //Range 设置第三参数 Range(开始位置,到达位置,步长)
        for(i <- Range(1,5,2)){
          println(i)
        }
        //to 模式 使用by关键字的后面添加步长
        for(i <- 1 to 5 by 2){
          println(i)
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    while循环和do…while循环
    //Scala中while循环和do-while循环和Java中是一样的
        //使用while循环打印 1~10之间数据
        var i = 1;
        while(i<=10){
          println(i);
          i+=1; //Scala中没有++运算符 需要使用是+=
        }
        //使用do-while循环打印10~1之间的数据
        var j = 10;
        do{
          println(j);
          j-=1;//Scala中没有--运算符 需要使用是-=
        }while(j>=1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    循环停止的三种方式
    //循环停止的三种方式
    object BreakLookDemo {
      //方式1:
      def add():Unit = {
        for(i <- 1 to 10){
          if(i == 7){
            return
          }
          println(i)
        }
      }
    
      def main(args: Array[String]): Unit = {
        //方式2:
        var flag = true
        var n = 0
        while (flag){
          n += 1
          println(n)
          if(n == 10){
            flag = false
          }
        }
        //for循环
        var flag1 = true
        for(i <- 0 to 10 if flag){
          println(i)
          if(i == 7){
            flag1 = false
          }
        }
        //方式3:
        import scala.util.control.Breaks._
        breakable{
          for(i <- 1 to 10){
            break
          }
        }
      }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    方法与函数定义

    方法与函数是两个不同的概念,函数是一个对象,可以赋值给一个变量

    类中声明的函数称之为方法

    函数没有重载、重写的概念

    定义函数\定义方法
    	/*
        一般在函数内部,针对方法赋值的位置
        提供函数体实现的时候,不提供返回值类型,由Scala自动推断
         */
        //说明:f1 函数名	()=>{} 具体实现(包含参数定义,实现函数逻辑)
    	val f1= (x:Int,y:Int)=>{x*y}//数据类型+返回值类型=函数类型
        //调用函数
        f1(1,2)
        //函数实现只有一行代码,可以省大括号
        val f2 = () => 2+3
        //还有一种形态
        //val函数名:(数据类型) => 返回值类型 = {(参数名) => 函数的实现}
        val f3:(Int) => Int = {(i) => i*100}
        //一行代码 简化
        val f4:(Int) => Int = i => i*100
        //无参无返回值
        val f5:() => Unit = () => print("你好")
        //定义方法
        def method:Unit = print("方法")
        //不是函数
        val f6=println("输出")
        //在源码中提供方法,使用大量函数数据类型作为方法的参数存在
        def method2(a:Int):Int=a*a
        //将方法手动转化为函数
        val f7=method2 _//方法转函数
        //调用某个方法,对参数进行传递,传递的是一个方法【Scala自动转】
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    /*
      定义方法:
      def 方法名(参数列表):返回值类型 = {
      提供方法体
      }
      ps:方法 函数有区分 类中定义写方法,方法内部实现 写函数
      scala中的方法 不仅可以定义在类中 而且可以写方法内容
       */
      //在类中定义一个 无返回值无参数的方法
      def method1():Unit ={
        println("这是一个方法")
      }
      def main(args: Array[String]): Unit = {
        //在类中调用方法【ps:Scala中没有static方法之分】
        //调用方法名(有参数提供,无参数则不提供--》需要返回值就接收 不需要接收直接调用即可)
        method1()
    
    //定义一个无参有返回值的方法
      def method2():String = {
        return "kaige"
      }
       val str:String = method2()
       println(method2())
    
       //有参无返回值-->
       def method3(username:String,password:String):Unit={
         println(username+password)
       }
      }
      //有参有返回值
      def method5(username:String):String={
        println(username)
        return username
      }
      //方法参数赋值 或默认
      def methodShow(message:String="get kaige"):Unit = {
        print(message)
      }
      //使用默认值
      methodShow()
      methodShow("kaige age is 50")
      //默认参数可以给多个,并且对位置没有要求
      def methodShow2(a:Int=1,b:Int,c:Int=3):Unit={
        println(a+b+c)
      }
      //调用方法是对参数有要求
      //不可以空参调用
      //methodShow2(2) 不可以这样赋值 Scala是顺序赋值
      methodShow2(b=2)
      //同时修改abc
      methodShow2(3,4,5)
      //顺序赋值针对b 必须对a也进行修改
      methodShow2(1,3)
      //可变参数--》允许同时传入多个参数
      //可变参数必须在所有参数的最后一个位置,赋值时可以是一个数组()但是需要转化
      def methodShow3(a:Int*):Unit={//方法中可以当作数组处理
        for(i<- a){
          println(i)
        }
      }
      //传参的时候,可以什么都没有,可以有多个 可以是数组
      methodShow3()
      methodShow3(1,23,44,5,6,6)
      val arr = Array(1,2,3)
     methodShow3(arr:_*)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    参数传递

    传名调用和传值调用

    先计算表达式的值,再应用到函数内部

    将未计算的表达式

    	//传值
        def addValue(a: Int, b: Int): Int = {
          return a + b
        }
        //传名调用
        def addName(a: Int, b: => Int): Int = {
          return a + b
        }
        //计算完毕传入方法内部
        val sum = addValue(1,2+2)
        //return 2+4
        println("传值调用:"+sum)
        //进入函数内部之前,传递方法、函数的引用,传递要使用方法内部进行执行调用
        val sum2 = addName(2,2+2)
        //return 2+(2+2)
        println("传名调用:"+sum2)
    
        //提供至简
        //提供一个方法,方法返回值是String类型
        def method1():String={
          //块表达式
          //不写reutrn
          "kaige"
        }
        //如果提供方法只有一句代码值,不写大括号
        def method2():String="kaige"
          //利用推到,利用最后一句代码自动推断 返回类型
        def mehtod3()="kaige"
        //没有参数列表 小括号都可以不写
        def method4 = "kaige"
        //没有参数的调用,需要区分是否存在小括号
        mehtod3()
        //method3
        method4
    
        def method5():String={
          return "kaige"
        }
        //unit,省返回类型和等于号
        def method6(): Unit ={
          println("11111")
        }
        //提供直接实现方法的方式
        ()=>{
          println("这是一个方法")
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    方法与函数的区别

    方法和函数的定义方式完全不同

    函数可以作为方法参数或返回值存储

    方法名是方法调用,而函数名只是代表函数对象本身

    方法使用def而函数使用val

    方法可以转换为函数,所以一般也不必严格区分

    • 自动转换:在需要函数的地方,如果传递一个方法,Scala能够自动把方法转换为函数
    • 手动转换 方法名 _

    两种方式将方法转换成函数

    1、把方法作为参数传给另一个方法或者函数的时候,方法自动被转化成函数。

    2、手动使用神奇的下划线_ 将方法被转化成函数:

    //自动转换方法到函数
        //这种常量多是定义方法被传递到另外一个方的参数中,会被Scala自动转换
        def m1(a:Int) = a*2;
        val arr = Array(1,2,3,4,5,6);
        arr.map(m1); //此时m1的方法会传递到map方法中会自动转换为函数
    
        //手动方法到函数
        val f7 = m1 _ // 【方法名 _】 把方法转换为函数
    
        //函数时可以赋值给变量,但是不允许将方法名赋值给变量
        // val f8 = m1;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    mysql 反斜杠\的坑
    IPV4流媒体C语言项目
    java数据结构与算法刷题-----LeetCode572. 另一棵树的子树(经典题,树字符串化KMP)
    硬件设计基础----三极管
    代码随想录|583. 两个字符串的删除操作,72. 编辑距离(有进一步理解到)
    现代卷积网络实战系列4:PyTorch从零构建VGGNet训练MNIST数据集
    java计算机毕业设计基于安卓Android微信小程序的共享单车租赁系统uniApp
    Qt第三十一章:渐变QGradient
    华为机考:HJ2 计算某字符出现次数
    【Java集合类面试六】、 HashMap有什么特点?
  • 原文地址:https://blog.csdn.net/Mr_Ren_0_1/article/details/126211164