Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

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の用法があると思うけど上には出てこない。

http://xawa99.blogspot.jp/2012/08/Scala-GetterSetter.html

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

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_= までがメソッド名で、英数字パートとイコールを繋げる文字としてアンダースコアがあるんだ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした