Scala的操作符:任何方法都可以是操作符
创始人
2024-04-18 10:01:13
0

Scala为它的基本类型提供了丰富的操作符集。这些操作符实际只是作用在普通方法调用上华丽的语法。例如,1 + 2与(1).+(2)其实是一回事。换句话说,就是Int类包含了叫做+的方法,它带一个Int参数并返回一个Int结果。这个+方法在两个Int相加时被调用:

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

  1. scala> val sum = 1 + 2 // Scala调用了(1).+(2)  
  2. sum: Int = 3 
想要证实这点,可以把表达式显式地写成方法调用:

  1. scala> val sumMore = (1).+(2)  
  2. sumMore: Int = 3 
而真正的事实是,Int包含了许多带不同的参数类型的重载:overload的+方法。重载的方法有同样的名称和不同的参数类型。例如,Int还有另一个也叫+的方法参数和返回类型为Long。如果你把Long加到Int上,这个替换的+方法就将被调用:

  1. scala> val longSum = 1 + 2L // Scala调用了(1).+(2L)  
  2. longSum: Long = 3 
符号+是操作符——更明确地说,是中缀操作符。操作符标注不仅限于像+这种其他语言里看上去像操作符一样的东西。你可以把任何方法都当作操作符来标注。例如,类String有一个方法indexOf带一个Char参数。indexOf方法搜索String里***次出现的指定字符,并返回它的索引或-1如果没有找到。你可以把indexOf当作中缀操作符使用,就像这样:

  1. scala> val s = "Hello, world!" 
  2. s: java.lang.String = Hello, world!  
  3. scala> s indexOf 'o' // Scala调用了s.indexOf(’o’)  
  4. res0: Int = 4 
另外,String提供一个重载的indexOf方法,带两个参数,分别是要搜索的字符和从哪个索引开始搜索。(前一个indexOf方法开始于索引零,也就是String开始的地方。)尽管这个indexOf方法带两个参数,你仍然可以用操作符标注的方式使用它。不过当你用操作符标注方式调用带多个参数的方法时,这些参数必须放在括号内。例如,以下是如何把另一种形式的indexOf当作操作符使用的例子(接前例):

  1. scala> s indexOf ('o', 5) // Scala调用了s.indexOf(’o’, 5)  
  2. res1: Int = 8 
任何方法都可以是操作符

Scala里的操作符不是特殊的语言语法:任何方法都可以是操作符。使用方法的方式使它成为操作符。如果写成s.indexOf('o'),indexOf就不是操作符。不过如果写成,s indexOf 'o',那么indexOf就是操作符了,因为你以操作符标注方式使用它。

目前为止,你已经看到了中缀:infix操作符标注的例子,也就是说调用的方法位于对象和传递给方法的参数或若干参数之间,如“7 + 2”。Scala还有另外两种操作符标注:前缀和后缀。前缀标注中,方法名被放在调用的对象之前,如,-7里的‘-’。后缀标注中,方法放在对象之后,如,“7 toLong”里的“toLong”。

与中缀操作符——操作符带后两个操作数,一个在左一个在右——相反,前缀和后缀操作符都是一元:unary的:它们仅带一个操作数。前缀方式中,操作数在操作符的右边。前缀操作符的例子有-2.0,!found和~0xFF。与中缀操作符一致,这些前缀操作符是在值类型对象上调用方法的简写方式。然而这种情况下,方法名在操作符字符上前缀了“unary_”。例如,Scala会把表达式-2.0转换成方法调用“(2.0).unary_-”。你可以输入通过操作符和显式方法名两种方式对方法的调用来演示这一点:

  1. scala> -2.0             // Scala调用了(2.0).unary_-  
  2. res2: Double = -2.0 
  3. scala> (2.0).unary_-  
  4. res3: Double = -2.0 
可以当作前缀操作符用的标识符只有+,-,!和~。因此,如果你定义了名为unary_!的方法,就可以像!p这样在合适的类型值或变量上用前缀操作符方式调用这个方法。但是如果你定义了名为unary_*的方法,就没办法用成前缀操作符了,因为*不是四种可以当作前缀操作符用的标识符之一。你可以像平常那用调用它,如p.unary_*,但如果尝试像*p这么调用,Scala就会把它理解为*.p,这或许就不会是你想当然的了!然而,不是一点儿希望都没有。仍然有极微弱的机会,让你的带有*p的程序或许能像C++那样被编译。

后缀操作符是不用点或括号调用的不带任何参数的方法。Scala里,你可以舍弃方法调用的空括号。例外就是如果方法带有副作用就加上括号,如println(),不过如果方法没有副作用就可以去掉括号,如String上调用的toLowerCase:

  1. scala> val s = "Hello, world!" 
  2. s: java.lang.String = Hello, world!  
  3. scala> s.toLowerCase  
  4. res4: java.lang.String = hello, world!  
后面的这个例子里,方法没带参数,或者还可以去掉点,采用后缀操作符标注方式:

  1. scala> s toLowerCase  
  2. res5: java.lang.String = hello, world!  
例子里,toLowerCase被当作操作数s上的后缀操作符。

因此要想知道Scala的值类型里你可以用哪些操作符,所有需要做的就是在Scala的API文档里查询定义在值类型上的方法。

【相关阅读】

  1. Scala的基本类型及文本化
  2. Scala程序及其Application特质
  3. Scala程序中的分号推断和Singleton对象
  4. 学习Scala类的定义,字段和方法
  5. 学习Scala脚本:从文件里读取行记录

相关内容

热门资讯

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