I've taken a look at the list of surveys taken on scala-lang.org and noticed a curious question: "Can you name all the uses of “_”?". Can you? If yes, please do so here. Explanatory examples are appreciated.
The ones I can think of are
Existential types
def foo(l: List[Option[_]]) = ...
Higher kinded type parameters
case class A[K[_],T](a: K[T])
Ignored variables
val _ = 5
Ignored parameters
List(1, 2, 3) foreach { _ => println("Hi") }
Ignored names of self types
trait MySeq { _: Seq[_] => }
Wildcard patterns
Some(5) match { case Some(_) => println("Yes") }
Wildcard patterns in interpolations
"abc" match { case s"a$_c" => }
Sequence wildcard in patterns
C(1, 2, 3) match { case C(vs # _*) => vs.foreach(f(_)) }
Wildcard imports
import java.util._
Hiding imports
import java.util.{ArrayList => _, _}
Joining letters to operators
def bang_!(x: Int) = 5
Assignment operators
def foo_=(x: Int) { ... }
Placeholder syntax
List(1, 2, 3) map (_ + 2)
Method values
List(1, 2, 3) foreach println _
Converting call-by-name parameters to functions
def toFunction(callByName: => Int): () => Int = callByName _
Default initializer
var x: String = _ // unloved syntax may be eliminated
There may be others I have forgotten!
Example showing why foo(_) and foo _ are different:
This example comes from 0__:
trait PlaceholderExample {
def process[A](f: A => Unit)
val set: Set[_ => Unit]
set.foreach(process _) // Error
set.foreach(process(_)) // No Error
}
In the first case, process _ represents a method; Scala takes the polymorphic method and attempts to make it monomorphic by filling in the type parameter, but realizes that there is no type that can be filled in for A that will give the type (_ => Unit) => ? (Existential _ is not a type).
In the second case, process(_) is a lambda; when writing a lambda with no explicit argument type, Scala infers the type from the argument that foreach expects, and _ => Unit is a type (whereas just plain _ isn't), so it can be substituted and inferred.
This may well be the trickiest gotcha in Scala I have ever encountered.
Note that this example compiles in 2.13. Ignore it like it was assigned to underscore.
From (my entry) in the FAQ, which I certainly do not guarantee to be complete (I added two entries just two days ago):
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_000_000 // Numeric literal separator (Scala 2.13+)
This is also part of this question.
An excellent explanation of the uses of the underscore is Scala _ [underscore] magic.
Examples:
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "anything other than one and two"
}
expr match {
case List(1,_,_) => " a list with three element and the first element is 1"
case List(_*) => " a list with zero or more elements "
case Map[_,_] => " matches a map with any key type and any value type "
case _ =>
}
List(1,2,3,4,5).foreach(print(_))
// Doing the same without underscore:
List(1,2,3,4,5).foreach( a => print(a))
In Scala, _ acts similar to * in Java while importing packages.
// Imports all the classes in the package matching
import scala.util.matching._
// Imports all the members of the object Fun (static import in Java).
import com.test.Fun._
// Imports all the members of the object Fun but renames Foo to Bar
import com.test.Fun.{ Foo => Bar , _ }
// Imports all the members except Foo. To exclude a member rename it to _
import com.test.Fun.{ Foo => _ , _ }
In Scala, a getter and setter will be implicitly defined for all non-private vars in a object. The getter name is same as the variable name and _= is added for the setter name.
class Test {
private var a = 0
def age = a
def age_=(n:Int) = {
require(n>0)
a = n
}
}
Usage:
val t = new Test
t.age = 5
println(t.age)
If you try to assign a function to a new variable, the function will be invoked and the result will be assigned to the variable. This confusion occurs due to the optional braces for method invocation. We should use _ after the function name to assign it to another variable.
class Test {
def fun = {
// Some code
}
val funLike = fun _
}
There is one usage I can see everyone here seems to have forgotten to list...
Rather than doing this:
List("foo", "bar", "baz").map(n => n.toUpperCase())
You could can simply do this:
List("foo", "bar", "baz").map(_.toUpperCase())
Here are some more examples where _ is used:
val nums = List(1,2,3,4,5,6,7,8,9,10)
nums filter (_ % 2 == 0)
nums reduce (_ + _)
nums.exists(_ > 5)
nums.takeWhile(_ < 8)
In all above examples one underscore represents an element in the list (for reduce the first underscore represents the accumulator)
Besides the usages that JAiro mentioned, I like this one:
def getConnectionProps = {
( Config.getHost, Config.getPort, Config.getSommElse, Config.getSommElsePartTwo )
}
If someone needs all connection properties, he can do:
val ( host, port, sommEsle, someElsePartTwo ) = getConnectionProps
If you need just a host and a port, you can do:
val ( host, port, _, _ ) = getConnectionProps
There is a specific example that "_" be used:
type StringMatcher = String => (String => Boolean)
def starts: StringMatcher = (prefix:String) => _ startsWith prefix
may be equal to :
def starts: StringMatcher = (prefix:String) => (s)=>s startsWith prefix
Applying “_” in some scenarios will automatically convert to “(x$n) => x$n ”
Related
In the following example using Scala 2.13.3 the 1st pattern matches, but the 2nd does not.
The 3rd pattern again matches, while the 4th does not (note that separator in the 4th match expression is enclosed in backticks, thus referencing the value defined before).
trait A
case object A extends A {
def unapply(a: String): Option[A] = if (a == "my_a") Some(A) else None
}
trait B
case object B extends B {
def unapply(b: String): Option[B] = if (b == "myB") Some(B) else None
}
val match1 = "myB_my_a" match {
case s"${B(b)}_${A(a)}" => Some((a,b))
case _ => None
} // Some((A,B))
val match2 = "my_a_myB" match {
case s"${A(a)}_${B(b)}" => Some((a,b))
case _ => None
} // None
val match3 = "my_a__myB" match {
case s"${A(a)}__${B(b)}" => Some((a,b))
case _ => None
} // Some((A,B))
val separator = "__"
val match4 = s"my_a${separator}myB" match {
case s"${A(a)}${`separator`}${B(b)}" => Some((a,b))
case _ => None
} // None
Why do only the 1st and the 3rd pattern match?
Is there a good matching alternative to the 2nd pattern that a) is using the unapply methods of A and B and where b) we don't know what strings these methods are accepting?
Edit 1: Added case object B and another matching example.
Edit 2: Another example to illustrate jwvh's answer:
val (a, b) = ("my_a", "myB")
val match5 = s"${a}_${b}" match {
case s"${`a`}_${`b`}" => Some((a, b)) // does not match
case s"${x}_${y}" => Some((x, y)) // matches: Some(("my", "a_myB"))
}
Edit 3: To illustrate how, unlike case class construction and extraction with apply and unapply, the construction and extraction of strings using similar string interpolation are not (and cannot be) inverse functions:
case class AB(a: String, b: String)
val id = (AB.apply _ tupled) andThen AB.unapply andThen (_.get)
val compare = id(("my_a", "myB")) == ("my_a", "myB") // true
val construct: (String, String) => String = (a,b) => s"${a}_${b}"
val extract: String => (String, String) = { case s"${a}_${b}" => (a,b) }
val id2 = (construct tupled) andThen extract
val compare2 = id2(("my_a","myB")) == ("my_a","myB") // false
As your own test (mentioned in the comments) demonstrates, the interpolator recognizes that the match pattern "${A(a)}_${B(b)}" is made up of 2 parts separated by an underscore _. So a best-guess effort is made to split the target string accordingly.
The 1st part, "my", is sent to the A.unapply() where it fails. The 2nd part, "a_myB", is not even attempted.
Something similar happens in match4. The pattern "${A(a)}${'separator'}${B(b)}" has 3 dollar signs and thus 3 parts. But, without any explicit characters to anchor the pattern, the target string is split into these 3 parts.
""
""
"my_a__myB"
Again, the 1st part fails the unapply() and the other parts are never attempted.
While your Edit 3 code is technically correct, I don't find it terribly convincing. You've simply demonstrated that (String,String)=>AB(String,String)=>(String,String) is (or can be) a lossless data transition. The same cannot be said of (String,String)=>String which introduces some ambiguity, i.e. the loss of information sufficient to guarantee restoration of the original data. That loss is inherent in the transformation itself, not the tools (interpolation) used to achieve it.
The fact that case class and String interpolation both use apply()/unapply() under the hood strikes me as inconsequential.
I've taken a look at the list of surveys taken on scala-lang.org and noticed a curious question: "Can you name all the uses of “_”?". Can you? If yes, please do so here. Explanatory examples are appreciated.
The ones I can think of are
Existential types
def foo(l: List[Option[_]]) = ...
Higher kinded type parameters
case class A[K[_],T](a: K[T])
Ignored variables
val _ = 5
Ignored parameters
List(1, 2, 3) foreach { _ => println("Hi") }
Ignored names of self types
trait MySeq { _: Seq[_] => }
Wildcard patterns
Some(5) match { case Some(_) => println("Yes") }
Wildcard patterns in interpolations
"abc" match { case s"a$_c" => }
Sequence wildcard in patterns
C(1, 2, 3) match { case C(vs # _*) => vs.foreach(f(_)) }
Wildcard imports
import java.util._
Hiding imports
import java.util.{ArrayList => _, _}
Joining letters to operators
def bang_!(x: Int) = 5
Assignment operators
def foo_=(x: Int) { ... }
Placeholder syntax
List(1, 2, 3) map (_ + 2)
Method values
List(1, 2, 3) foreach println _
Converting call-by-name parameters to functions
def toFunction(callByName: => Int): () => Int = callByName _
Default initializer
var x: String = _ // unloved syntax may be eliminated
There may be others I have forgotten!
Example showing why foo(_) and foo _ are different:
This example comes from 0__:
trait PlaceholderExample {
def process[A](f: A => Unit)
val set: Set[_ => Unit]
set.foreach(process _) // Error
set.foreach(process(_)) // No Error
}
In the first case, process _ represents a method; Scala takes the polymorphic method and attempts to make it monomorphic by filling in the type parameter, but realizes that there is no type that can be filled in for A that will give the type (_ => Unit) => ? (Existential _ is not a type).
In the second case, process(_) is a lambda; when writing a lambda with no explicit argument type, Scala infers the type from the argument that foreach expects, and _ => Unit is a type (whereas just plain _ isn't), so it can be substituted and inferred.
This may well be the trickiest gotcha in Scala I have ever encountered.
Note that this example compiles in 2.13. Ignore it like it was assigned to underscore.
From (my entry) in the FAQ, which I certainly do not guarantee to be complete (I added two entries just two days ago):
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_000_000 // Numeric literal separator (Scala 2.13+)
This is also part of this question.
An excellent explanation of the uses of the underscore is Scala _ [underscore] magic.
Examples:
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "anything other than one and two"
}
expr match {
case List(1,_,_) => " a list with three element and the first element is 1"
case List(_*) => " a list with zero or more elements "
case Map[_,_] => " matches a map with any key type and any value type "
case _ =>
}
List(1,2,3,4,5).foreach(print(_))
// Doing the same without underscore:
List(1,2,3,4,5).foreach( a => print(a))
In Scala, _ acts similar to * in Java while importing packages.
// Imports all the classes in the package matching
import scala.util.matching._
// Imports all the members of the object Fun (static import in Java).
import com.test.Fun._
// Imports all the members of the object Fun but renames Foo to Bar
import com.test.Fun.{ Foo => Bar , _ }
// Imports all the members except Foo. To exclude a member rename it to _
import com.test.Fun.{ Foo => _ , _ }
In Scala, a getter and setter will be implicitly defined for all non-private vars in a object. The getter name is same as the variable name and _= is added for the setter name.
class Test {
private var a = 0
def age = a
def age_=(n:Int) = {
require(n>0)
a = n
}
}
Usage:
val t = new Test
t.age = 5
println(t.age)
If you try to assign a function to a new variable, the function will be invoked and the result will be assigned to the variable. This confusion occurs due to the optional braces for method invocation. We should use _ after the function name to assign it to another variable.
class Test {
def fun = {
// Some code
}
val funLike = fun _
}
There is one usage I can see everyone here seems to have forgotten to list...
Rather than doing this:
List("foo", "bar", "baz").map(n => n.toUpperCase())
You could can simply do this:
List("foo", "bar", "baz").map(_.toUpperCase())
Here are some more examples where _ is used:
val nums = List(1,2,3,4,5,6,7,8,9,10)
nums filter (_ % 2 == 0)
nums reduce (_ + _)
nums.exists(_ > 5)
nums.takeWhile(_ < 8)
In all above examples one underscore represents an element in the list (for reduce the first underscore represents the accumulator)
Besides the usages that JAiro mentioned, I like this one:
def getConnectionProps = {
( Config.getHost, Config.getPort, Config.getSommElse, Config.getSommElsePartTwo )
}
If someone needs all connection properties, he can do:
val ( host, port, sommEsle, someElsePartTwo ) = getConnectionProps
If you need just a host and a port, you can do:
val ( host, port, _, _ ) = getConnectionProps
There is a specific example that "_" be used:
type StringMatcher = String => (String => Boolean)
def starts: StringMatcher = (prefix:String) => _ startsWith prefix
may be equal to :
def starts: StringMatcher = (prefix:String) => (s)=>s startsWith prefix
Applying “_” in some scenarios will automatically convert to “(x$n) => x$n ”
I've taken a look at the list of surveys taken on scala-lang.org and noticed a curious question: "Can you name all the uses of “_”?". Can you? If yes, please do so here. Explanatory examples are appreciated.
The ones I can think of are
Existential types
def foo(l: List[Option[_]]) = ...
Higher kinded type parameters
case class A[K[_],T](a: K[T])
Ignored variables
val _ = 5
Ignored parameters
List(1, 2, 3) foreach { _ => println("Hi") }
Ignored names of self types
trait MySeq { _: Seq[_] => }
Wildcard patterns
Some(5) match { case Some(_) => println("Yes") }
Wildcard patterns in interpolations
"abc" match { case s"a$_c" => }
Sequence wildcard in patterns
C(1, 2, 3) match { case C(vs # _*) => vs.foreach(f(_)) }
Wildcard imports
import java.util._
Hiding imports
import java.util.{ArrayList => _, _}
Joining letters to operators
def bang_!(x: Int) = 5
Assignment operators
def foo_=(x: Int) { ... }
Placeholder syntax
List(1, 2, 3) map (_ + 2)
Method values
List(1, 2, 3) foreach println _
Converting call-by-name parameters to functions
def toFunction(callByName: => Int): () => Int = callByName _
Default initializer
var x: String = _ // unloved syntax may be eliminated
There may be others I have forgotten!
Example showing why foo(_) and foo _ are different:
This example comes from 0__:
trait PlaceholderExample {
def process[A](f: A => Unit)
val set: Set[_ => Unit]
set.foreach(process _) // Error
set.foreach(process(_)) // No Error
}
In the first case, process _ represents a method; Scala takes the polymorphic method and attempts to make it monomorphic by filling in the type parameter, but realizes that there is no type that can be filled in for A that will give the type (_ => Unit) => ? (Existential _ is not a type).
In the second case, process(_) is a lambda; when writing a lambda with no explicit argument type, Scala infers the type from the argument that foreach expects, and _ => Unit is a type (whereas just plain _ isn't), so it can be substituted and inferred.
This may well be the trickiest gotcha in Scala I have ever encountered.
Note that this example compiles in 2.13. Ignore it like it was assigned to underscore.
From (my entry) in the FAQ, which I certainly do not guarantee to be complete (I added two entries just two days ago):
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_000_000 // Numeric literal separator (Scala 2.13+)
This is also part of this question.
An excellent explanation of the uses of the underscore is Scala _ [underscore] magic.
Examples:
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "anything other than one and two"
}
expr match {
case List(1,_,_) => " a list with three element and the first element is 1"
case List(_*) => " a list with zero or more elements "
case Map[_,_] => " matches a map with any key type and any value type "
case _ =>
}
List(1,2,3,4,5).foreach(print(_))
// Doing the same without underscore:
List(1,2,3,4,5).foreach( a => print(a))
In Scala, _ acts similar to * in Java while importing packages.
// Imports all the classes in the package matching
import scala.util.matching._
// Imports all the members of the object Fun (static import in Java).
import com.test.Fun._
// Imports all the members of the object Fun but renames Foo to Bar
import com.test.Fun.{ Foo => Bar , _ }
// Imports all the members except Foo. To exclude a member rename it to _
import com.test.Fun.{ Foo => _ , _ }
In Scala, a getter and setter will be implicitly defined for all non-private vars in a object. The getter name is same as the variable name and _= is added for the setter name.
class Test {
private var a = 0
def age = a
def age_=(n:Int) = {
require(n>0)
a = n
}
}
Usage:
val t = new Test
t.age = 5
println(t.age)
If you try to assign a function to a new variable, the function will be invoked and the result will be assigned to the variable. This confusion occurs due to the optional braces for method invocation. We should use _ after the function name to assign it to another variable.
class Test {
def fun = {
// Some code
}
val funLike = fun _
}
There is one usage I can see everyone here seems to have forgotten to list...
Rather than doing this:
List("foo", "bar", "baz").map(n => n.toUpperCase())
You could can simply do this:
List("foo", "bar", "baz").map(_.toUpperCase())
Here are some more examples where _ is used:
val nums = List(1,2,3,4,5,6,7,8,9,10)
nums filter (_ % 2 == 0)
nums reduce (_ + _)
nums.exists(_ > 5)
nums.takeWhile(_ < 8)
In all above examples one underscore represents an element in the list (for reduce the first underscore represents the accumulator)
Besides the usages that JAiro mentioned, I like this one:
def getConnectionProps = {
( Config.getHost, Config.getPort, Config.getSommElse, Config.getSommElsePartTwo )
}
If someone needs all connection properties, he can do:
val ( host, port, sommEsle, someElsePartTwo ) = getConnectionProps
If you need just a host and a port, you can do:
val ( host, port, _, _ ) = getConnectionProps
There is a specific example that "_" be used:
type StringMatcher = String => (String => Boolean)
def starts: StringMatcher = (prefix:String) => _ startsWith prefix
may be equal to :
def starts: StringMatcher = (prefix:String) => (s)=>s startsWith prefix
Applying “_” in some scenarios will automatically convert to “(x$n) => x$n ”
If you have a pattern matching (case) in Scala, for example:
foo match {
case a: String => doSomething(a)
case f: Float => doSomethingElse(f)
case _ => ? // How does one determine what this was?
}
Is there a way to determine what type was actually caught in the catch-all?
case x => println(x.getClass)
Too easy :-)
Basically, you just need to bind the value in your catch-all statement to a name (x in this case), then you can use the standard getClass method to determine the type.
If you're trying to perform specific logic based on the type, you're probably doing it wrong. You could compose your match statements as partial functions if you need some 'default' cases that you don't want to define inline there. For instance:
scala> val defaultHandler: PartialFunction[Any, Unit] = {
| case x: String => println("String: " + x)
| }
defaultHandler: PartialFunction[Any,Unit] = <function1>
scala> val customHandler: PartialFunction[Any, Unit] = {
| case x: Int => println("Int: " + x)
| }
customHandler: PartialFunction[Any,Unit] = <function1>
scala> (customHandler orElse defaultHandler)("hey there")
String: hey there
foo match {
case a: String => doSomething(a)
case f: Float => doSomethingElse(f)
case x => println(x.getClass)
}
I've taken a look at the list of surveys taken on scala-lang.org and noticed a curious question: "Can you name all the uses of “_”?". Can you? If yes, please do so here. Explanatory examples are appreciated.
The ones I can think of are
Existential types
def foo(l: List[Option[_]]) = ...
Higher kinded type parameters
case class A[K[_],T](a: K[T])
Ignored variables
val _ = 5
Ignored parameters
List(1, 2, 3) foreach { _ => println("Hi") }
Ignored names of self types
trait MySeq { _: Seq[_] => }
Wildcard patterns
Some(5) match { case Some(_) => println("Yes") }
Wildcard patterns in interpolations
"abc" match { case s"a$_c" => }
Sequence wildcard in patterns
C(1, 2, 3) match { case C(vs # _*) => vs.foreach(f(_)) }
Wildcard imports
import java.util._
Hiding imports
import java.util.{ArrayList => _, _}
Joining letters to operators
def bang_!(x: Int) = 5
Assignment operators
def foo_=(x: Int) { ... }
Placeholder syntax
List(1, 2, 3) map (_ + 2)
Method values
List(1, 2, 3) foreach println _
Converting call-by-name parameters to functions
def toFunction(callByName: => Int): () => Int = callByName _
Default initializer
var x: String = _ // unloved syntax may be eliminated
There may be others I have forgotten!
Example showing why foo(_) and foo _ are different:
This example comes from 0__:
trait PlaceholderExample {
def process[A](f: A => Unit)
val set: Set[_ => Unit]
set.foreach(process _) // Error
set.foreach(process(_)) // No Error
}
In the first case, process _ represents a method; Scala takes the polymorphic method and attempts to make it monomorphic by filling in the type parameter, but realizes that there is no type that can be filled in for A that will give the type (_ => Unit) => ? (Existential _ is not a type).
In the second case, process(_) is a lambda; when writing a lambda with no explicit argument type, Scala infers the type from the argument that foreach expects, and _ => Unit is a type (whereas just plain _ isn't), so it can be substituted and inferred.
This may well be the trickiest gotcha in Scala I have ever encountered.
Note that this example compiles in 2.13. Ignore it like it was assigned to underscore.
From (my entry) in the FAQ, which I certainly do not guarantee to be complete (I added two entries just two days ago):
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_000_000 // Numeric literal separator (Scala 2.13+)
This is also part of this question.
An excellent explanation of the uses of the underscore is Scala _ [underscore] magic.
Examples:
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "anything other than one and two"
}
expr match {
case List(1,_,_) => " a list with three element and the first element is 1"
case List(_*) => " a list with zero or more elements "
case Map[_,_] => " matches a map with any key type and any value type "
case _ =>
}
List(1,2,3,4,5).foreach(print(_))
// Doing the same without underscore:
List(1,2,3,4,5).foreach( a => print(a))
In Scala, _ acts similar to * in Java while importing packages.
// Imports all the classes in the package matching
import scala.util.matching._
// Imports all the members of the object Fun (static import in Java).
import com.test.Fun._
// Imports all the members of the object Fun but renames Foo to Bar
import com.test.Fun.{ Foo => Bar , _ }
// Imports all the members except Foo. To exclude a member rename it to _
import com.test.Fun.{ Foo => _ , _ }
In Scala, a getter and setter will be implicitly defined for all non-private vars in a object. The getter name is same as the variable name and _= is added for the setter name.
class Test {
private var a = 0
def age = a
def age_=(n:Int) = {
require(n>0)
a = n
}
}
Usage:
val t = new Test
t.age = 5
println(t.age)
If you try to assign a function to a new variable, the function will be invoked and the result will be assigned to the variable. This confusion occurs due to the optional braces for method invocation. We should use _ after the function name to assign it to another variable.
class Test {
def fun = {
// Some code
}
val funLike = fun _
}
There is one usage I can see everyone here seems to have forgotten to list...
Rather than doing this:
List("foo", "bar", "baz").map(n => n.toUpperCase())
You could can simply do this:
List("foo", "bar", "baz").map(_.toUpperCase())
Here are some more examples where _ is used:
val nums = List(1,2,3,4,5,6,7,8,9,10)
nums filter (_ % 2 == 0)
nums reduce (_ + _)
nums.exists(_ > 5)
nums.takeWhile(_ < 8)
In all above examples one underscore represents an element in the list (for reduce the first underscore represents the accumulator)
Besides the usages that JAiro mentioned, I like this one:
def getConnectionProps = {
( Config.getHost, Config.getPort, Config.getSommElse, Config.getSommElsePartTwo )
}
If someone needs all connection properties, he can do:
val ( host, port, sommEsle, someElsePartTwo ) = getConnectionProps
If you need just a host and a port, you can do:
val ( host, port, _, _ ) = getConnectionProps
There is a specific example that "_" be used:
type StringMatcher = String => (String => Boolean)
def starts: StringMatcher = (prefix:String) => _ startsWith prefix
may be equal to :
def starts: StringMatcher = (prefix:String) => (s)=>s startsWith prefix
Applying “_” in some scenarios will automatically convert to “(x$n) => x$n ”