千家信息网

Scala传名参数by-name parameter怎么使用

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"Scala传名参数by-name parameter怎么使用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔
千家信息网最后更新 2026年11月02日Scala传名参数by-name parameter怎么使用

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

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怎么使用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

参数 函数 类型 代码 括号 表达式 之间 例子 方式 标志 评估 东西 内容 差别 情况 方法 更多 知识 尝试 合法 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州大一互联网络科技有限公司 北京路客互联网科技有限公司 港股互联网科技股 电子科技大学互联网 沃里互联网科技 万达互联网科技 互联网前沿科技 互联网养老 桔豆科技 恒生科技互联网指数分析 宁夏科技产业互联网案例 浙江互联网科技研学营 赶超互联网科技 微信多开 知域互联网科技有限公司大骗子 成都互联网科技公司工作好不好 烟台灵鸽互联网科技有限公司 富国互联网科技002692 安徽零酒互联网科技有限公司 互联网大会出现的黑科技 伍佰万互联网科技是干嘛的 广州全民伙伴互联网科技有限公司 互联网科技的 上海互联网科技有限公司 狮子座互联网科技 易通互联网络科技有限公司 友谊互联网络科技 科技大学互联网专业好不好 沐思想互联网科技有限公司 郑州欣桑互联网科技有限公司 九思连强互联网电子科技有限公司 互联网科技收购价值
0