控制抽象之传名参数

我们来看这个例子:

package scala

object ScalaTest3 {
    def main(args : Array[String]) : Unit = {
        runInThread(()=>println("Hi"))
        Thread.sleep(5000)
        println("Bye")
    }
    def runInThread(block:()=>Unit){
        new Thread{
            override def run(){
                block()            
            }
        }.start()
    }
}

上例中,runInThread方法参数以类型为 ( ) => Unit 的函数的形式给出。不过,当你调用该函数时,需要写一段不那么美观 ( ) => ,如上例:

runInThread(() => println("Hi"))

要想在调用中省掉 () =>,以及在参数声明中省略 ()[这像这样:block: => Unit,注意冒号与等号之间有空格],可以使用传名参数

package scala

object ScalaTest3 {
    def main(args : Array[String]) : Unit = {
        runInThread(println("Hi"))      //注意这里
        Thread.sleep(5000)
        println("Bye")
    }
    def runInThread(block: => Unit){    //注意这里
        new Thread{
            override def run {
                block        
            }
        }.start()
    }
}

关于传名参数的定义,我们先来看看传值的参数传名的参数的区别:

Scala的解释器在解析函数参数(function arguments)时有两种方式:先计算参数表达式的值(reduce the arguments),再应用到函数内部;或者是将未计算的参数表达式直接应用到函数内部。前者叫做传值调用(call-by-value),后者叫做传名调用(call-by-name)。

不过要使用传名参数,有两点要注意:1. 必须是无参函数作为另一个函数的参数。2. 作为参数的函数声明中必须省略 (),另外函数调用时必须省略 ()=>。见另一个例子:

package scala

object ScalaTest3 {
    var assertionsEnabled = true
    def main(args : Array[String]) : Unit = {
        byNameAssert(5 > 3)
    }
    def byNameAssert(predicate: => Boolean) = 
        if(assertionsEnabled && !predicate) throw new AssertionError
}

使用传名参数的函数就是传名函数。要实现一个传名函数,要定义参数的类型开始于 => 而不是开始于 ()=>。如上例,可以通过改变其类型“() => Boolean”为“=>Boolean”,把myAssert的predicate参数改为传名参数

我们再来看看传名函数的一个非常重要的特点传名参数求值不会先于传名函数调用,这与按值传递不一样。下面我们先看一个按值传递的例子:

def boolAssert(predicate:Boolean) = 
    if(assertionsEnabled && !predicate) throw new AssertionError

这个例子与前一个例子之间存在一个非常重要的差别。因为boolAssert的参数类型是Boolean,在boolAssert(5>3)里,括号中的表达式先于boolAssert的调用被评估。表达式 5 > 3产生true,被传给boolAssert。相对的,因为byNameAssert的predicate参数的类型是 =>Boolean,byNameAssert(5 > 3)里括号中的表达式不是先于byNameAssert的调用被评估的。而是代之以先创建一个函数值,其apply方法将评估 5 > 3,而这个函数值将被传递给byNameAssert

转载于:https://my.oschina.net/fhd/blog/280373

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值