Scala의 underscore(_)란?

요즘 자꾸 스칼라랑 부딫히게 되네요. 써본적도 없는 언어지만 다른 언어랑 비슷하거니(Js+Java느낌..) 하고 봤는데, 어마무시하게 가독성을 떨어뜨리는 무언가를 발견하였습니다.

_(Under bar)가 굉장히 많은 곳에 쓰이는데, 다들 의미가 좀 달라보여서 찾아보니 Underscore라고 불리는 문법(?) 중 하나였습니다.

Underscore에 대한 slideshare ppt 문서의 코드만 봐도 자꾸 _ 가 나타납니다..

class Underscores {
    import collection.{ Map => _ , _ }

    var count : Int = _

    def sum = (_:Int) + (_:Int)
    def sum2(a:Int)(b:Int) = a+b
    def offset = sum2(count) _

    def sizeOf(l:Traversable[_]) : Unit = l match {
        case it:Iterable[Int] => count = (0/:it)(_ + _)
        case s:Seq[_] => s.foreach( _ => count = count + 1)
        case _ => println(offset(l.size))
    }
}

(https://www.slideshare.net/normation/scala-dreaded 문서 내 코드 일부)

간략하게 정리 해볼겸 글 작성해봅니다. (이걸 쓴다고 이해가될 것 같진 않네요.. 그냥 가끔씩 참고하는 정도만)

(_) Underscore?

Underscore(_)는 Scala에서 wildcard, ignore 등 여러가지 의미로 쓰입니다.

  1. Existential types
def foo(l: List[Option[_]]) = ...
  1. Higher kinded type parameters
case class A[K[_],T](a: K[T])
  1. Ignored 이름없이 임의의 param, var, type 등으로 사용할 수 있습니다.
//Ignored variables
val _ = 5

// Ignored parameters
List(1, 2, 3) foreach { _ => println("Hi") }

// Ignored names of self types
trait MySeq { _: Seq[_] => }
  1. Wildcard patterns, Wildcard imports import , code 내 여러 부분에서 Wildcard(*)와 동일한 역할을 수행합니다.
import java.util._

Some(5) match { case Some(_) => println("Yes") }
  1. Hiding imports import 시 특정 헤더들은 제외해서 할 수 있습니다. 아래의 경우는 ArrayList 관련 헤더는 제외하고 로드합니다.
import java.util.{ArrayList => _, _}
  1. Joining letters to punctuation
def bang_!(x: Int) = 5
  1. Assignment operators
def foo_=(x: Int) { ... }
  1. Placeholder syntax
List(1, 2, 3) map (_ + 2)
Partially applied functions
List(1, 2, 3) foreach println _
  1. Converting call-by-name parameters to functions
def toFunction(callByName: => Int): () => Int = callByName _

등등..더 있는 것 같긴한데 찾아본바로는 이런 의미들로 쓰이는 것 같습니다. 스칼라를 통해서 개발할껀 아니지만, 코드단에서 취약점 찾으려면 이런 문법은 어느정도 숙지해둬야 편할 것 같네요..

Reference

https://www.slideshare.net/normation/scala-dreaded https://charsyam.wordpress.com/2015/03/03/입-개발-scala의-거시기-_underscore-의-용법-정리/