tl;dr
class C
defines a class, just as in Java or C++.
object O
creates a singleton object O
as instance of some anonymous class; it can be used to hold static members that are not associated with instances of some class.
object O extends T
makes the object O
an instance of trait T
; you can then pass O
anywhere, a T
is expected.
- if there is a
class C
, then object C
is the companion object of class C
; note that the companion object is not automatically an instance of C
.
Also see Scala documentation for object and class.
object
as host of static members
Most often, you need an object
to hold methods and values/variables that shall be available without having to first instantiate an instance of some class.
This use is closely related to static
members in Java.
object A {
def twice(i: Int): Int = 2*i
}
You can then call above method using A.twice(2)
.
If twice
were a member of some class A
, then you would need to make an instance first:
class A() {
def twice(i: Int): Int = 2 * i
}
val a = new A()
a.twice(2)
You can see how redundant this is, as twice
does not require any instance-specific data.
object
as a special named instance
You can also use the object
itself as some special instance of a class or trait.
When you do this, your object needs to extend some trait
in order to become an instance of a subclass of it.
Consider the following code:
object A extends B with C {
...
}
This declaration first declares an anonymous (inaccessible) class that extends both B
and C
, and instantiates a single instance of this class named A
.
This means A
can be passed to functions expecting objects of type B
or C
, or B with C
.
Additional Features of object
There also exist some special features of objects in Scala.
I recommend to read the official documentation.
def apply(...)
enables the usual method name-less syntax of A(...)
def unapply(...)
allows to create custom pattern matching extractors
- if accompanying a class of the same name, the object assumes a special role when resolving implicit parameters
Your solution is fine. You could introduce a type alias for Function1[X, Unit]
; use ()
as per Kevin's answer, and drop unnecessary parens.
scala> type Effect[-A] = (A => Unit)
defined type alias Effect
scala> def foo(f: Effect[String] = _ => ()) = ()
foo: (f: (String) => Unit)Unit
You could also define a noop
function:
scala> val noop = (a: Any) => ()
noop: (Any) => Unit = <function1>
scala> def foo(f: Effect[String] = noop) = ()
Best Solution
If you want to pattern match on the array to determine whether the second element is the empty string, you can do the following:
The
_*
binds to any number of elements including none. This is similar to the following match on Lists, which is probably better known: