在Scala中定义无参数方法
创始人
2024-04-19 02:10:25
0

作为下一步,我们将向Element添加显示宽度和高度的方法,展示在代码10.2中。height方法返回contents里的行数。width方法返回***行的长度,或如果元素没有行记录,返回零。(也就是说你不能定义一个高度为零但宽度不为零的元素。)

  1. abstract class Element {  
  2.  def contents: Array[String]  
  3.  def height: Int = contents.length  
  4.  def width: Int = if (height == 0) 0 else contents(0).length  
  5. }  

代码 10.2 定义无参数方法width和height

51CTO编辑推荐:Scala编程语言专题

请注意Element的三个方法没一个有参数列表,甚至连个空列表都没有。例如,代之以:

  1. def width(): Int  
方法定义了不加括号的:

  1. def width: Int  
这种无参数方法在Scala里是非常普通的。相对的,带有空括号的方法定义,如def height(): Int,被称为空括号方法:empty-paren method。推荐的惯例是在没有参数并且方法仅通过读含有对象的方式访问可变状态(专指其不改变可变状态)时,使用无参数方法。这个惯例支持统一访问原则:uniform access principleMeyer,面向对象软件构造【Mey00】就是说客户代码不应受通过字段还是方法实现属性的决定的影响。例如,我们可以选择把width和height作为字段而不是方法来实现,只要简单地在每个实现里把def修改成val即可:

  1. abstract class Element {  
  2.  def contents: Array[String]  
  3.  val height = contents.length  
  4.  val width =  
  5.   if (height == 0) 0 else contents(0).length  
  6. }  
两组定义从客户的观点来看是完全相同的。唯一的差别是与的访问或许稍微比方法调用要快,因为字段值在类被初始化的时候被预计算,而方法调用在每次调用的时候都要计算。换句话说,字段在每个Element对象上需要更多的内存空间。因此类的使用概况,属性表达成字段还是方法更好,决定了其实现,并且这个概况还可以随时改变。重点是Element类的客户不应在其内部实现改变的时候受影响。

特别是如果类的字段变成了访问函数,且访问函数是纯的,就是说它没有副作用并且不依赖于可变状态,那么类Element的客户不需要被重写。客户都不应该需要关心这些。

目前为止一切良好。但仍然有些琐碎的复杂的东西要去做以协同Java处理事情的方式。问题在于Java没有实现统一访问原则。因此Java里是string.length(),不是string.length(尽管是array.length,不是array.length())。不用说,这让人很困惑。

为了在这道缺口上架一座桥梁,Scala在遇到混合了无参数和空括号方法的情况时很大度。特别是,你可以用空括号方法重载无参数方法,并且反之亦可。你还可以在调用任何不带参数的方法时省略空的括号。例如,下面两行在Scala里都是合法的:

  1. Array(1, 2, 3).toString  
  2. "abc".length  
原则上Scala的函数调用中可以省略所有的空括号。然而,在调用的方法表达的超过其接收调用者对象的属性时,推荐仍然写一对空的括号。例如,如果方法执行了I/O,或写入可重新赋值的变量(var),或读出不是接受调用者的字段的var,无论是直接的还是非直接的通过使用可变对象,那么空括号是合适的。这种方式是让参数列表扮演一个可见的线索说明某些有趣的计算正通过调用被触发。例如:

  1. "hello".length // 没有副作用,所以无须()  
  2. println() // ***别省略()  

总结起来,Scala里定义不带参数也没有副作用的方法为无参数方法,也就是说,省略空的括号,是鼓励的风格。另一方面,永远不要定义没有括号的带副作用的方法,因为那样的话方法调用看上去会像选择一个字段。这样你的客户看到了副作用会很奇怪。相同地,当你调用带副作用的函数,请确信写这个调用的时候包括了空的括号。另一种考虑这个问题的方式是,如果你调用的函数执行了操作,使用括号,但如果仅提供了对某个属性的访问,省略括号。

【相关阅读】

  1. 学习Scala的二维布局库和抽象类
  2. Scala学习:叫名参数by-name parameter
  3. Scala:如何编写新的控制结构
  4. Scala学习:Curry化的函数
  5. Scala学习:简化客户代码

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...