暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Scala 学习 4:函数

技术白小白 2019-06-01
194

Scala 函数式编程

  • Scala 函数和方法

在Scala中,函数和方法几乎何以等同(定义,使用,运行机制都一样),只是函数的使用相对灵活多样。

def main(args: Array[String]): Unit = {
println(sum(1,2))
// 方法转函数
val f1 = sum _
println(f1(30,10))
// 函数
val f2 = (n1:Int, n2:Int) => {
n1 + n2
}
println(f2)
}

/**
* 求和 方法
* @param n1
* @param n2
* @return
*/
def sum(n1:Int, n2:Int): Int = {
n1 + n2
}

复制

函数式编程: 在Scala中,像变量一样,函数既可以作为函数的参数使用,也可以把函数赋值给一个变量。

  • 递归
    一个函数在函数体内有调用了自身,则为递归调用。

object Demo01 {

def main(args: Array[String]): Unit = {
test(4) // 输出 2,3,4
}

def test(n: Int): Unit ={
if (n > 2){
test(n-1)
}
println(n)
}
}

复制
  1. 程序执行函数是,就创建一个新的受保护的独立空间,与多线程一样,是新的函数栈。

  2. 函数的局部变量是相互独立的,不受相互影响

  3. 递归必须有退出条件,而且必须向退出条件逼近,否则就会无线递归,抛出栈溢出异常。

  4. 当一个函数执行完毕,或者遇到return,就会返回,谁调用就将结果返回给谁。

  • 函数调用及注意事项

  1. 函数的形参可以是多个,如果函数没有形参,调用时可以不用() 

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

  3. Scala函数可以根据函数体最后一行代码自行推断函数返回值类型,这种情况下return关键字可以省略

    def test(n1: Int, n2:Int):Int = {
    n1 + n2
    }

    复制
  4. 因为Scala可以自行推断,所以在生来return关键字的地方,返回值类型也可以省略

    def test(n1: Int, n2:Int) = {
    n1 + n2
    }

    复制
  5. 如果函数申明return关键字,那么函数返回值就不能使用自行推断了,这是要明确写成 :返回值类型 =, 如果返回值什么都不写(申明Unit),即表示该函数没有返回值,这是即使写了return,return也不生效。

    def test(n1: Int, n2:Int):Int = {
    return n1 + n2
    }

    // 此处该函数没有返回值
    def test1(n1: Int, n2:Int) {
    return n1 + n2
    }

    // 此处没有返回值
    def test2(n1: Int, n2:Int):Unit = {
    return n1 + n2
    }

    复制
  6. 如果函数没有返回值或不确定返回值,那么返回值类型可以省略(或者申明为Any)

    def f1(s:String) = {
    if(s.length >= 3)
    s + "123"
    else
    3
    }

    // 两个函数相同
    def f2(s:String):Any = {
    if(s.length >= 3)
    s + "123"
    else
    3
    }

    复制
  7. Scala语法中任何语法结构都可以嵌套其他语法结构(相当灵活),即函数中可以再申明函数, 类中可以再声明类,方法中可以在声明/定义方法

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

    /**
    * 此处f1在底层被声明为private final
    */
    def f1():Unit = {
    println("f1")
    }

    println("ok~")

    def sayOk():Unit = { // private final sayOk$1()
    println("main sayOk")
    def sayOk():Unit = { // private final sayOk$2()
    println("sayOk sayOk")
    }
    }
    }

    /**
    * 成员
    */
    def sayOk():Unit = {
    println("main sayOK")
    }
    }

    复制
  8. Scala函数的形参,在申明参数时,直接赋初始默认值,这时如果调用函数时,如果没有指定 形参,则会使用默认值。如果指定了实参,则实参会覆盖默认值。

    def main(args: Array[String]): Unit = {
    println(sayHello()) // 输出 hello ok
    println(sayHello("haha")) // 输出 haha ok
    }
    def sayHello(name:String = "hello") = {
    name + " ok"
    }

    复制
  9. 如果函数存在多个参数,每一个参数都可以设置默认值,此时按照从左到右申明,这种情况下可以使用带名参数

    def main(args: Array[String]): Unit = {
    mysqlCon("127.0.0.1", 3310) // 从左到右覆盖
    mysqlCon(user = "test", pwd = "test123") // 带名参数,修改指定参数
    }

    def mysqlCon(host: String = "localhost", port: Int = 3306,
    user: String = "root", pwd: String = "root") = {
    println("host=" + host)
    println("port=" + port)
    println("user=" + user)
    println("pwd=" + pwd)
    }

    复制
  10. Scala函数的形参默认是val的,因此不能在函数中进行修改

  11. 递归函数未执行之前时无法推断出返回结果类型,在使用时必须有明确的返回值类型

    // 此处必须要指定返回类型
    def f1(n:Int): Int = {
    if (n==1)
    1
    else
    f1(n-1)
    }

    复制
  12. Scala支持可变参数,可变参数只能放在形参列表的最后

    /**
    * 支持0到多个参数, args是个seq
    * @param args
    */
    def sum(args: Int*) = {
    }

    /**
    * 支持一到多个参数
    * @param n1
    * @param args
    */
    def sum(n1: Int, args: Int*) = {
    }

    复制


文章转载自技术白小白,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论