LoginSignup
187
171

More than 5 years have passed since last update.

Scalaでアンダースコアの意味が分からなかったらここを見る

Last updated at Posted at 2015-06-11

コードを読んでてアンダースコア出てきたけど調べられないときのために。

import scala._    // Wild card -- all of Scala is imported
import scala.{ Predef => _, _ } // Exception, everything except Predef
def f[M[_]]       // Higher kinded type parameter
def f(m: M[_])    // Existential type
_ + _             // Anonymous function placeholder parameter
m _               // Eta expansion of method into method value
m(_)              // Partial function application
_ => 5            // Discarded parameter
case _ =>         // Wild card pattern -- matches anything
val (a, _) = (1, 2) // same thing
for (_ <- 1 to 10)  // same thing
f(xs: _*)         // Sequence xs is passed as multiple parameters to f(ys: T*)
case Seq(xs @ _*) // Identifier xs is bound to the whole matched sequence
var i: Int = _    // Initialization to the default value
def abc_<>!       // An underscore must separate alphanumerics from symbols on identifiers
t._2              // Part of a method name, such as tuple getters

いくつかコメント

1

import scala.{ Predef => _, _ }

ワイルドカードインポートだけど特定のパッケージはインポートしないためのものらしい。

2

_ + _

reduceLeft とかで使うやつだけど、これだけで無名関数を表すことができるらしい。

scala> List(1,2,3).reduceLeft(_ + _)
res12: Int = 6

scala> val a: ((Int, Int) => Int) = _ + _
a: (Int, Int) => Int = <function2>

3

m _
m(_)

の違いはStackOverflowに書いてあるけど理解して使える気がしない。

trait PlaceholderExample {
  def process[A](f: A => Unit)

  val set: Set[_ => Unit]

  set.foreach(process _) // Error 
  set.foreach(process(_)) // No Error
}

4

f(xs: _*)

これは可変長引数の関数にSeqを渡すときの記法。

scala> def sum(xs: Int*) = xs.reduceLeft(_ + _)
sum: (xs: Int*)Int

scala> val list = List(1, 2)
list: List[Int] = List(1, 2)

scala> sum(list: _*)
res5: Int = 3

5

case Seq(xs @ _*)

これはこういうやつらしい。一番忘れそう。アットマークはこれ以外にも使われるのだろうか。

scala> List(1, 2) match { case Seq(xs @ _*) => println(xs) }
List(1, 2)

6

var i: Int = _

デフォルト値で初期化。試したところ、IntとかDouble以外はnullで初期化された。使い所なさそう。

scala> var i: Int = _
i: Int = 0

scala> var i: Double = _
i: Double = 0.0

scala> var i: Map[Int, Int] = _
i: Map[Int,Int] = null

scala> case class A(a: Int)
defined class A

scala> var i: A = _
i: A = null

scala> var i: Option[Int] = _
i: Option[Int] = null

7

setterの用法があると思うけど上には出てこない。

「 _= で終わるメソッドは _= を除いた部分に対する代入文として呼び出せる」

scala> class Data(private var value_ : Int) {
     |     def value : Int = value_;
     |     def value_=(newValue : Int) = value_ = newValue;
     | }
defined class Data

scala> val d = new Data(1)
d: Data = Data@6ee52dcd

scala> println(d.value)
1

scala> d.value = 2
d.value: Int = 2

scala> println(d.value)
2

追記

↑のパターンは

def abc_<>!       // An underscore must separate alphanumerics from symbols on identifiers

と同じか。

value_= までがメソッド名で、英数字パートとイコールを繋げる文字としてアンダースコアがあるんだ。

187
171
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
187
171