• Scala语言学习笔记——方法、函数及异常


    1.Scala 方法及函数区别
     ① Scala 有方法与函数,二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法

     ② Scala 中的方法跟 Java 的类似,方法是组成类的一部分

     ③ Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象

     ④ Scala 中使用 val 语句可以定义函数,def 语句定义方法和函数

    class Test {
    def method (x: Int) = x + 3
    val function = (x: Int) => x + 3
    }
    2.Scala 方法
    ① 方法的声明语法

       基本语法

          def 方法名 ([参数名: 参数类型], ...)[[: 返回值类型] =] {

              语句...

              return 返回值

         }

        说明:[ ] 表示可选,可以有,也可以没有,如果不写 = {},等于号和方法主体,那么该方法会被隐式声明为抽象(abstract),包含他的类型也是也是一个抽象类型

        1) 方法声明关键字为def  (definition)

        2) [参数名: 参数类型],... :表示函数的参数列表,可以没有。 如果有,多个参数使用逗号间隔

        3) 方法中的语句:表示为了实现某一功能代码块

        4) 方法可以有返回值,也可以没有

        5) 返回值形式1:  : 返回值类型  =  

    def getRes(n1: Int, n2: Int, oper: Char): Int = {
    n1 + n2
    }
        6) 返回值形式2: =  表示返回值类型不确定,使用类型推导完成

    def getRes(n1: Int, n2: Int, oper: Char):Int = { //方法声明处的返回值:Int
    if (oper == '+') {
    n1 + n2
    } else if (oper == '-') {
    n1 - n2
    } else {
    null //运行报错
    }
    }
        注意:因为null是AnyRef的子类,但是null不是AnyVal的子类,这儿编译不会报错,但是运行会报typeError异常,如果非要返回null,则可以将方法返回值 :Int 去掉,直接使用 = 号,Scala会自动进行返回类型推断

        7) 返回值形式3:       表示没有返回值,return 不生效

    def getRes(n1: Int, n2: Int, oper: Char) {
    return n1 + n2 //代码运行正常,但是return不生效
    }
        8) 如果没有return,默认以执行到最后一行的结果作为返回值

    ② 方法注意事项

     1)方法的形参列表可以是多个, 如果方法没有形参,调用时可以不带()

     2)形参列表和返回值列表的数据类型可以是值类型和引用类型

     3)Scala中的方法可以根据方法体最后一行代码自行推断方法返回值类型。那么在这种情况下,return关键字可以省略

     4)因为Scala可以自行推断,所以在省略return关键字的场合,返回值类型也可以省略

     5)如果方法明确使用return关键字,那么方法返回就不能使用自行推断了,这时要明确写成 : 返回类型 =  ,当然如果你什么都不写,即使有return 返回值为()

    def getSum(n1: Int, n2: Int) = { // = 号不能省略,如果省略了,就表示没有返回值,res得到的就是()
    n1 + n2
    }
     6)如果方法明确声明无返回值(声明Unit),那么方法体中即使使用return关键字也不会有返回值

     7)如果明确方法无返回值或不确定返回值类型,那么返回值类型可以省略(或声明为Any)

     8)Scala语法中任何的语法结构都可以嵌套其他语法结构(灵活),即:方法中可以再声明/定义方法,类中可以再声明类 ,方法中可以再声明/定义方法

    object TestDef {
    def main(args: Array[String]): Unit = {
    //main函数中再声明/定义方法sayHello
    def sayHello(name: String): String = {
    def sayHello(name: String): String = {
    name + " hello"
    }
    sayHello(name)
    }
    var r = sayHello("terry")
    println("r=" + r) //r=terry hello
    }
    }
     9)Scala方法的形参,在声明参数时,直接赋初始值(默认值),这时调用方法时,如果没有指定实参,则会使用默认值。如果指定了实参,则实参会覆盖默认值

    object Test {
    def main(args: Array[String]): Unit = {
    println(sayOk())
    println(sayOk("Tom")) //覆盖默认值
    }
    def sayOk(name : String = "jack"): String = {
    return name + " ok! "
    }
    }
    10)如果方法存在多个参数,每一个参数都可以设定默认值,那么这个时候,传递的参数到底是覆盖默认值,还是赋值给没有默认值的参数,就不确定了(默认按照声明顺序[从左到右])。在这种情况下,可以采用带名参数

    /**
    * @author huleikai
    * @create 2019-05-17 11:56
    */
    object TestDefArgs {
    def main(args: Array[String]): Unit = {
    mysqlCon() //不传参则使用默认值
    mysqlCon("127.0.0.1", 8080) //按默认参数顺序对应覆盖
    mysqlCon(pwd = "123456") //使用带名参数覆盖某个默认值
    }

    def mysqlCon(add: String = "localhost", port: Int = 3306,
    user: String = "root", pwd: String = "root"): Unit = {
    println("add=" + add)
    println("port=" + port)
    println("user=" + user)
    println("pwd=" + pwd)
    }
    }
     11)Scala 方法的形参默认是val的,因此不能在方法中进行修改

     12)递归方法未执行之前是无法推断出来结果类型,在使用时必须有明确的返回值类型

     13)Scala方法支持可变参数

    def sum(args :Int*) : Int = {}
    3.Scala 函数
        函数与方法大致一样,但在scala中,函数的概念更为重要与广泛,并且更为灵活。

      ① 定义一个函数

       类似方法的定义规则:

    def abs (x: Double) = if (x > 0) x else -x
      在函数不是递归函数的情况下,scala可以通过=后面的表达式推断出返回值类型。但是,一旦函数是递归的,那么你也需要显示指定返回值类型:

    def res(n: Int): Int = if (n < 0) 1 else n * res(n-1)
      ② 匿名函数

       Scala 中定义匿名函数的语法很简单,箭头左边是参数列表,右边是函数体。使用匿名函数后,我们的代码变得更简洁了。

       下面的表达式就定义了一个接受一个Int类型输入参数的匿名函数:

    val add = (x:Int,y:Int) => x+y
      上述定义的匿名函数,其实是下面这种写法的简写:

    def add = new Function1[Int,Int]{
    def apply(x:Int):Int = x+1;
    }
     add 现在可作为一个函数,使用方式如下:

    println(add(3, 4))
     我们也可以不给匿名函数设置参数,如下所示:

    val emptyFunc = () => { println("Hello Scala!") }
     上面我们说过,如果一个方法无参数列表,则可以调用的时候直接写方法名即可,但是无参匿名函数调用时则必须带上()括号

    println( emptyFunc() )
    4.方法和函数的相互转化及使用
        因为函数本身其实就是一个继承了Trait的对象,所以将函数当做方法的参数传参自然没什么问题,相当于java中的方法的自定义Student类的对象传参一样,所以函数既可以当做方法的参数传入,也可以当做函数的参数传入

      

       而方法本身不能直接当做参数,但可以先转化为函数再进行传参,如果在一个方法或函数的参数中传入符合参数类型条件的方法,那么Scala编译器会默认将该方法转化为函数传入

      

      当然方法也可以使用方法名+空格+_将方法转化为函数,如下图所示:

      

    5.Scala 的异常Exception
     ① Scala 异常处理举例

    try {
    val num = 10 / 0
    } catch {
    case ex: ArithmeticException => println("捕获了除数为零的算数异常")
    case ex: Exception => println("捕获了异常")
    } finally {
    //最终要执行的代码
    println("scala finally...")
    }
    ② Scala自定义异常类

       在Scala中,可以创建自己的异常。它也称为自定义异常。通过扩展Exception类,同时声明自定义异常类。在自定义类中创建自己的异常消息。下面我们来看一个例子:
     

    //声明一个异常类继承Exception
    class InvalidAgeException(s: String) extends Exception(s) {}

    class ExceptionExample {
    @throws(classOf[InvalidAgeException])
    def validate(age: Int) {
    if (age < 18) {
    throw new InvalidAgeException("Not eligible")
    } else {
    println("You are eligible")
    }
    }
    }

    object Demo {
    def main(args: Array[String]) {
    var e = new ExceptionExample()
    try {
    e.validate(5)
    } catch {
    case e: Exception => println("Exception Occured : " + e)
    }
    }
    }
    ③ Scala异常处理总结

      1)Scala的异常的工作机制和Java一样,但是Scala没有 checked(编译期) 异常,即Scala没有编译异常这个概念,异常都是在运行的时候捕获处理

      2)用throw关键字,抛出一个异常对象。所有异常都是Throwable的子类型。throw表达式是有类型的,就是Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方

    def main(args: Array[String]): Unit = {
    val res = test()
    println (res.toString)
    }
    def test(): Nothing = {
    throw new Exception("出现异常")
    }
      3)在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码块中,是一系列case子句来匹配对应的异常。类似 java 的 switch case x: 代码块

      4)异常捕捉的机制与其他语言中一样,如果有异常发生,catch子句是按次序捕捉的。因此,在catch子句中,越具体的异常越要靠前,越普遍的异常越靠后,如果把越普遍的异常写在前,把具体的异常写在后,在scala中也不会报错,但这样是非常不好的编程风格

      5)Scala提供了throws关键字来声明异常。可以使用方法定义声明异常。 它向调用者函数提供了此方法可能引发此异常的信息。 它有助于调用函数处理并将该代码包含在try-catch块中,以避免程序异常终止。在scala中,可以使用throws注释来声明异常

    def main(args: Array[String]): Unit = {
    f11()
    }
    @throws(classOf[NumberFormatException]) //等同于NumberFormatException.class
    def f11() = {"abc".toInt}
     
    --------------------- 

  • 相关阅读:
    Atitit.android js 的键盘按键检测Back键Home键和Menu键事件
    Atitit  OOCSS vs bem
    Atitit.js模块化 atiImport 的新特性javascript import
    Atitit.css 规范 bem 项目中 CSS 的组织和管理
    Atitit.eclipse git使用
    Atitit jOrgChart的使用  组织架构图css html
    Atitit.java相比c#.net的优点 优缺点  v2 q330
    Atitit.判断元素是否显示隐藏在父元素 overflow
    Atitit.获得向上向下左的右的邻居的方法 软键盘的设计..
    Atitit..css的体系结构
  • 原文地址:https://www.cnblogs.com/ly570/p/10947719.html
Copyright © 2020-2023  润新知