Scala传名参数by-nameparameter怎么使用

本篇内容介绍了“Scala传名参数by-name parameter怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

创新互联专业IDC数据服务器托管提供商,专业提供成都服务器托管,服务器租用,郑州服务器托管郑州服务器托管,成都多线服务器托管等服务器托管服务。

withPrintWriter方法需要一个类型为PrintWriter的参数。这个参数以“writer =>”方式显示出来:

withPrintWriter(file) {   writer => writer.println(new java.util.Date)  }

然而如果你想要实现某些更像if或while的东西,根本没有值要传入大括号之间的代码,那该怎么做呢?为了解决这种情况,Scala提供了传名参数。

为了举一个有现实意义的例子,请设想你需要实现一个称为myAssert的断言架构。你只能称其为myAssert,而不是assert,因为Scala提供了它自己的assert,将在14.1节描述。myAssert函数将带一个函数值做输入并参考一个标志位来决定该做什么。如果标志位被设置了,myAssert将调用传入的函数并证实其返回true。如果标志位被关闭了,myAssert将安静地什么都不做。

如果没有传名参数,你可以这样写myAssert:

var assertionsEnabled = true def myAssert(predicate: () => Boolean) =   if (assertionsEnabled && !predicate())    throw new AssertionError

这个定义是正确的,但使用它会有点儿难看:

myAssert(() => 5 > 3)

你或许很想省略函数文本里的空参数列表和=>符号,写成如下形式:

myAssert(5 > 3) // 不会有效,因为缺少() =>

传名函数恰好为了实现你的愿望而出现。要实现一个传名函数,要定义参数的类型开始于=>而不是() =>。例如,你可以通过改变其类型,“() => Boolean”,为“=> Boolean”,把myAssert的predicate参数改为传名参数。代码9.5展示了它的样子:

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

代码 9.5 使用传名参数

现在你可以在需要断言的属性里省略空的参数了。使用byNameAssert的结果看上去就好象使用了内建控制结构:

byNameAssert(5 > 3)

传名类型中,空的参数列表,(),被省略,它仅在参数中被允许。没有什么传名变量或传名字段这样的东西。

现在,你或许想知道为什么你不能简化myAssert的编写,使用陈旧的Boolean作为它参数的类型,如:

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

当然这种格式同样合法,并且使用这个版本boolAssert的代码看上去仍然与前面的一样:

boolAssert(5 > 3)

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

因此这两种方式之间的差别,在于如果断言被禁用,你会看到boolAssert括号里的表达式的某些副作用,而byNameAssert却没有。例如,如果断言被禁用,boolAssert的例子里尝试对“x / 0 == 0”的断言将产生一个异常:

scala> var assertionsEnabled = false assertionsEnabled: Boolean = false scala> boolAssert(x / 0 == 0)  java.lang.ArithmeticException: / by zero   at .< init>(< console>:8)   at .< clinit>(< console>)   at RequestResult$.< init>(< console>:3)   at RequestResult$.< clinit>(< console>)...

但在byNameAssert的例子里尝试同样代码的断言将不产生异常:

scala> byNameAssert(x / 0 == 0)

“Scala传名参数by-name parameter怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!


网站标题:Scala传名参数by-nameparameter怎么使用
当前网址:http://bzwzjz.com/article/ppddhc.html

其他资讯

Copyright © 2007-2020 广东宝晨空调科技有限公司 All Rights Reserved 粤ICP备2022107769号
友情链接: 企业网站设计 成都网站建设 LED网站设计方案 网站制作公司 成都响应式网站建设 响应式网站设计方案 高端网站设计 成都营销网站建设 响应式网站设计 成都营销网站制作 成都网站建设 成都品牌网站设计 成都网站设计 成都网站建设 网站建设方案 公司网站建设 手机网站制作设计 高端网站设计推广 手机网站建设 网站制作 上市集团网站建设 网站建设费用