Scala系列5、Scala中的函数

1、方法中的return是可以缺省的,scala会将函数的最后一句作为返回值;
   方法还可以缺省返回值类型,scala会自动进行类型推断,但是如果是递归函数就必须指定返回这类型。但是最好还是不要省略返回值类型
2、scala中的参数和Java中的参数不太一样。Java参数有形参和实参的区别,但在scala中有时形参和实参是一致的。参看【scala指定函数参数名】
3、=>左侧表示输入,右侧表示转换操作
4、scala函数中的参数都是val的,所以不能在函数体内再次给参数赋值
    
5、Scala定义函数的方法
6、函数的传值调用和传名调用:传值调用就是普通意义上的调用;着重说下传名调用。其语法是: def addByName(a: => Int) = a 比传值调用多了一个=>,传名调用只有在函数体中实际调用时才会计算表达式的值,只是两个调用方式的最大区别。
   
     Scala除了支持面向对象之外,还是一门函数式语言,因此函数是Scala的核心。
    定义函数,需要给出函数的名字、参数和函数体:
def method(x: Int) = if(x>0) x else -x
    函数需要给出所有参数的类型。只要函数不递归是可以不写return,scala可以根据=右边的式子推导出函数的返回值类型。
    函数要定义在object中,红框中的叫函数声明。如果不写等号和方法体,则方法会被隐式的声明为“抽象abstract”。对于函数的调用,跟Java的方式一样。使用对应的函数名,如果有参数,传入对应的参数即可调用。
    如果函数体需要多个表达式来完成需求,可是使用代码块。代码块中的最后一句就是函数的返回值。如下例:如果要使用return返回 a+b的值,则必选要标明函数的返回类型

【过程】
    scala对于不返回值的函数有特使的表示方法:如果函数体包含在花括号中但是没有前面的=,那么返回类型就是Unit,这样的函数就叫做过程。过程不返回值,调用过程是为了使用它的副作用。如:我们需要打印一些图案,那么就可以定义如下过程:
def main(args: Array[ String ]): Unit = {
draw("123")
}

//draw(s:String){}  对于没有返回这的过程,这种写法也是对的
def draw(s: String ): Unit ={
println("-----")
println("|"+" "+"|")
println("|"+s+"|")
println("|"+" "+"|")
println("-----")
}

 

【默认参数值】
    在scala函数中,可以为函数的参数指定默认值。当我们调用这个函数没有给参数传值的时候,就会启用默认参数值。如果指定了参数值,就会使用指定的参数值。
    在下面这个例子中的第三个输出语句中,我们还可以不按照参数顺序来传值,但是需要在传值的时候指定参数名
object HelloWorld {
     def main(args: Array[ String ]): Unit = {
          println ( outputBook ( "book1" ));
          println ( outputBook ( "book2" , "[" , "]" ));
          println ( outputBook (right= "***]" ,bookname = "book3" ))
}
def outputBook(bookname: String ,left: String = "{" ,right: String = "}" ) =    left + bookname + right;
}

//运行结果
{book1}
[book2]
{book3***]

【可变参数】
    scala支持可变参数,实现方式与Java稍有不同。scala的变长参数是用 * 声明。本例中,如果想要实现一个序列作为参数传入,需要追加 _*,意思就是告诉编译器把这个参数当做参数序列处理。
    直接传入一个序列使错误的,因为这这个例子中,传入的参数被限制为单个参数,所以直接传入一个整数区间是不被接受的。解决办法就是在序列后面追加 _*,来告诉编译器我们希望这个参数被当做单数序列处理。
def main(args: Array[ String ]): Unit = {
     println ( sum ( 1 , 2 , 3 , 4 , 5 ))
     // 序列作为参数
     println ( sum ( 1 to 5 : _*))
}
// 变长参数
def sum(args: Int*): Int ={
     var res = 0
     for (n <- args){
          res += n;
     }
     return res;
}



///
【Scala指定函数参数名】
    通常情况下,我们想调用一个参数都是按照函数定义的参数顺序一个个传递。在scala中我们也可以通过指定函数的参数名,而不一定需要按照函数定义的参数顺序向函数传递参数。
def main(args: Array[ String ]): Unit = {

printInt (b= 5 , a= 8 );
}

def printInt(a: Int, b: Int): Unit = {
println (a);
println (b);


【Scala函数的调用】
    1、传值调用,这种方式就是Java中最常见的函数调用方式。
def main(args: Array[ String ]): Unit = {

    var increase = (x: Int) => x+ 1
    println(increase(10))
    println("2:"+increase2(13))


}

//相当于这种形式  这种写法是极简写法,省略了返回类型、返回值和方法体的括号
def increase2(x: Int) = x+ 1 ;

//如果是多个语句的情况
val increaseAnother = (x: Int) =>{
    println("多条语句")
    println ( " 请使用 \" {} \" " )
    x + 1
}
println (increaseAnother( 12 ))

    2、传名调用,将未计算的表达式传进函数。传名调用的语法是:在使用传名调用时,在参数名称和参数类型之间有一个"=>"符号。传名调用是在函数内部进行表达式值计算的。而传值调用在传入函数内部之前就已经把参数表达式的值计算完毕。
    示例代码如下:
    =>左侧表示输入,右侧表示转换操作
def main(args: Array[ String ]): Unit = {
    //函数的传名调用
    delayed(time())
}

def time() ={
    println("time方法,获取时间")
    System.nanoTime()
}
def delayed(t: => Long) = {
    println("delayed方法中调用time方法");
    //在真正调用参数t的时候才会开始计算t的值
    println("参数t:"+t);
    //又调用了一次time()来计算t的值
    t
}
    在main方法中我们调用了delayed方法,传的参数是time()。delayed方法通过 =>符号来设置传名调用。 
    运行结果:
    在运行的时候,首先进入delayed方法。接着delayed方法打印了接收到的值,这一步就在delayed内部执行了time方法。最后再次通过参数t调用了time()方法。

【匿名函数】
    scala中定义匿名函数的语法很简单。箭头左边是参数列表,右边是函数体
def main(args: Array[ String ]): Unit = {
//定义一个匿名函数
var inc = (x: Int) => x+ 1 ;
    println(inc(20))
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值