Java
Scala

Scalaでのメソッド呼び出しの書き方一覧と推奨される書き方

More than 3 years have passed since last update.


メソッド呼び出しの基本形はJavaと同じ

  オブジェクト.メソッド(引数, 引数...)


メソッド呼び出しの書き方一覧

先ずは非推奨な書き方も含めて呼び出せる全ての形式をコードに書いてみる。

////でコメントアウトしてある行は使用できない形式になる。

class Hoge {

//引数リストがないメソッド
def f1 = 1
//引数がないメソッド
def f2() = 1
//引数が1つのメソッド
def f3(x: Int) = x * 2
//引数が複数のメソッド
def f4(x: Int, y: Int) = x * y
}

//引数リストがないメソッド
////hoge.f1()
////hoge f1()
hoge.f1 //> res0: Int = 1
hoge f1 //> res1: Int = 1
//空行は伊達じゃないよ

//引数がないメソッド
hoge.f2() //> res2: Int = 1
hoge.f2 //> res3: Int = 1
hoge f2() //> res4: Int = 1
hoge f2 //> res5: Int = 1
//空行は伊達じゃないよ

//引数が1つのメソッド
hoge.f3(1) //> res6: Int = 2
hoge f3(1) //> res7: Int = 2
hoge f3 1 //> res8: Int = 2
hoge.f3 { 1 } //> res9: Int = 2
hoge f3 { 1 } //> res10: Int = 2
////hoge.f3 1

//引数が複数のメソッド
hoge.f4(1, 2) //> res11: Int = 2
hoge f4(1, 2) //> res12: Int = 2
////hoge.f4 1, 2
////hoge f4 1, 2


  • 引数リストがないメソッドは()を付けて呼び出すことはできない。

  • 引数が1つのメソッドは()の代わりに{}を使うことができる。


  • .は省略できる。

  • 引数がないメソッドは()を省略できる

  • 引数が1つのメソッドでも()を省略できるが、この場合.も同時に省略しなければならない。


用語説明

推奨される書き方を説明する前に、その中で使用する用語について少し説明しておく。


中置記法

引数が1つのメソッドで.()を省略した形式を中置記法という。


中置記法の形式

オブジェクト メソッド名 引数



後置記法

引数リストがないメソッドと引数がないメソッドで.()を省略した形式を後置記法という。


後置記法の形式

オブジェクト メソッド名


後置記法は行末でしか使えない。

また、次の行は空行にしなければならない。


副作用

呼び出した時に戻り値以外に何らかの影響を与えるメソッドを「副作用があるメソッド」という。


  • java.util.Listのclear()メソッドはListオブジェクトの状態を変更するので「副作用があるメソッド」

  • java.util.Listのsize()メソッドはListオブジェクトの状態を変更しないので「副作用がないメソッド」

  • System.out.println()はコンソール出力を行うので「副作用があるメソッド」


推奨される書き方

////でコメントアウトしている行は推奨されない書き方。


引数がないメソッド


副作用がない場合は()を省略してもよい

val javaList = new java.util.ArrayList[Int]()     //> javaList  : java.util.ArrayList[Int] = []


javaList.size() //> res13: Int = 0
javaList.size //> res14: Int = 0


副作用がある場合は()を省略してはいけない

javaList.clear()

////javaList.clear


後置記法は原則使用しない

////javaList size

////javaList clear


引数が1つのメソッド


副作用があるメソッドは()を省略してはいけない

javaList.add(1)                                   //> res15: Boolean = true

////javaList add 1


副作用がない場合は中置記法で書いてもよい

javaList.indexOf(1)                               //> res16: Int = 0

javaList indexOf 1 //> res17: Int = 0


演算子のように使うメソッドは中置記法で書いた方がわかりやすい

1.max(2)                                          //> res18: Int = 2

1 max 2 //> res19: Int = 2

0.to(3) //> res20: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)
0 to 3 //> res21: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)

"abc".concat("def") //> res22: String = abcdef
"abc" concat "def" //> res23: String = abcdef


引数が複数のメソッド


副作用の有無に関係なく.は省略しない

javaList.add(0, 2)

javaList.subList(1, 2) //> res24: java.util.List[Int] = [1]
////javaList add(0, 2)
////javaList subList(1, 2)


関数を渡すメソッド


引数が1つのメソッドで関数を渡す場合は中置記法で{}を使ってもよい

val nums = Array(1, 2, 3)                         //> nums  : Array[Int] = Array(1, 2, 3)


nums.exists(_ < 0) //> res25: Boolean = false
nums exists { _ < 0 } //> res26: Boolean = false


処理が複数行になる場合は{}のほうがシンプルになる

nums.filter(i => {

val tmp = i.toBinaryString
tmp.exists(_ == '0')
}) //> res27: Array[Int] = Array(2)
nums.filter { i =>
val tmp = i.toBinaryString
tmp.exists { _ == '0' }
}


中置記法のメソッドチェインの最後では後置記法を使っても良い

nums.filter(_ >= 2).map(_ * 2).toList             //> res28: List[Int] = List(4, 6)

nums filter { _ >= 2 } map { _ * 2 } toList //> res29: List[Int] = List(4, 6)


どう書けばいいか迷った時

とりあえずJavaと同じ形式で書いとけ。非推奨ではないから。


参考

Scalaスタイルガイド

Scalaメモ(Hishidama's Scala Memo)