Any method can be an operator

scala 的方法可當成運算子,運算子也可當成方法

以 Int 為例,Int 定義了許多運算子的方法,例如:+,-,*,/,!=,to,…

scala> val sum = (1).+(5)
sum: Int = 6

scala> val sum = 1 + 5
sum: Int = 6

scala> val nums = 1 to 5
nums: scala.collection.immutable.Range.Inclusive = Range 1 to 5

Int 也實作了許多 overload 可帶入不同型態的參數,overload 就是方法名稱一樣但傳入參數的型態及數量會不一樣. 如果方法參數都一樣,return type 不一樣還是不能 overload :

scala> class Hello {
     |  def hi(name:String) : String = "Hi " + name
     |  def hi(name:String) : Int = 1
     | }
<console>:13: error: method hi is defined twice;
  the conflicting method hi was defined at line 12:6
        def hi(name:String) : Int = 1
            ^

scala> class Hello {
     |  def hi(name:String) : String = "Hi " + name
     |  def hi(name:Int) : Int = 1
     | }
defined class Hello

像 + 就可傳入許多不同型態的參數,回傳型態也不一樣 :

scala> val sum = 1 + 2
sum: Int = 3

scala> val sum = 1 + "2"
sum: String = 12

scala> val sum = 1 + 2D
sum: Double = 3.0

scala> val sum = 1 + 2L
sum: Long = 3

再來看 String,String 的 api 裡有提供 concat 這方法,也可以把他當成運算子使用 :

scala> val msg = "Hi "
msg: String = "Hi "

scala> val newMsg = msg concat "Jack"
newMsg: String = Hi Jack

String 的 toLowerCase ,把 toLowerCase 當作方法呼叫 :

scala> newMsg.toLowerCase
res1: String = hi jack

prefix operators 、 infix operator 、 Postfix operators

  • prefix operators 是 +, -, !, and ~
scala> -5
res1: Int = -5
  • infix operator 就是在物件及方法參數的中間運算子.
scala> 1 + 5
res2: Int = 6
  • Postfix operators 是沒有帶參數的方法.
scala> 5 toLong
<console>:12: warning: postfix operator toLong should be enabled
by making the implicit value scala.language.postfixOps visible.
This can be achieved by adding the import clause 'import scala.language.postfixOps'
or by setting the compiler option -language:postfixOps.
See the Scaladoc for value scala.language.postfixOps for a discussion
why the feature should be explicitly enabled.
       5 toLong
         ^
res3: Long = 5

toLowerCase 也算是 Postfix operators,需要 import scala.language.postfixOps 才不會出現 warning :

scala> newMsg toLowerCase
<console>:13: warning: postfix operator toLowerCase should be enabled
by making the implicit value scala.language.postfixOps visible.
This can be achieved by adding the import clause 'import scala.language.postfixOps'
or by setting the compiler option -language:postfixOps.
See the Scaladoc for value scala.language.postfixOps for a discussion
why the feature should be explicitly enabled.
       newMsg toLowerCase
              ^
res2: String = hi jack

scala> import scala.language.postfixOps
import scala.language.postfixOps

scala> newMsg toLowerCase
res3: String = hi jack

總結


  • 在 scala 裡 operators are methods & any method can be an operator,就看程式的寫法.