You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In Scala, patterns can be defined independently of case classes. To this end, a method named unapply is defined to yield a so-called extractor. An extractor can be thought of as a special method that reverses the effect of applying a particular object on some inputs. Its purpose is to 'extract' the inputs that were present before the 'apply' operation. For instance, the following code defines an extractor [object](singleton-objects.html) Twice.
14
+
An extractor object is an object with an `unapply` method. Whereas the `apply`method is like a constructor which takes arguments and creates an object, the `unapply` takes an object and tries to give back the arguments. This is most often used in pattern matching and partial functions.
x match { case Twice(n) => Console.println(n) } // prints 21
29
+
val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908
30
+
customer1ID match {
31
+
case CustomerID(name) => println(name) // prints Sukyoung
32
+
case _ => println("Could not extract a CustomerID")
25
33
}
26
34
```
27
35
28
-
There are two syntactic conventions at work here:
36
+
The `apply` method creates a `CustomerID` string from a `name`. The `unapply` does the inverse to get the `name` back. When we call `CustomerID("Sukyoung")`, this is shorthand syntax for calling `CustomerID.apply("Sukyoung")`. When we call `case CustomerID(name) => customer1ID`, we're calling the unapply method.
29
37
30
-
The pattern `case Twice(n)` will cause an invocation of `Twice.unapply`, which is used to match any even number; the return value of the `unapply` signals whether the argument has matched or not, and any sub-values that can be used for further matching. Here, the sub-value is `z/2`
38
+
The unapply method can also be used to assign a value.
31
39
32
-
The `apply` method is not necessary for pattern matching. It is only used to mimick a constructor. `val x = Twice(21)` expands to `val x = Twice.apply(21)`.
40
+
```tut
41
+
val customer2ID = CustomerID("Nico")
42
+
val CustomerID(name) = customer2ID
43
+
println(name) // prints Nico
44
+
```
45
+
46
+
This is equivalent to `val name = CustomerID.unapply(customer2ID).get`. If there is no match, a `scala.MatchError` is thrown:
47
+
48
+
```tut:fail
49
+
val CustomerID(name2) = "--asdfasdfasdf"
50
+
```
33
51
34
52
The return type of an `unapply` should be chosen as follows:
35
53
36
54
* If it is just a test, return a `Boolean`. For instance `case even()`
37
55
* If it returns a single sub-value of type T, return an `Option[T]`
38
56
* If you want to return several sub-values `T1,...,Tn`, group them in an optional tuple `Option[(T1,...,Tn)]`.
39
57
40
-
Sometimes, the number of sub-values is fixed and we would like to return a sequence. For this reason, you can also define patterns through `unapplySeq`. The last sub-value type `Tn` has to be `Seq[S]`. This mechanism is used for instance in pattern `case List(x1, ..., xn)`.
41
-
42
-
Extractors can make code more maintainable. For details, read the paper ["Matching Objects with Patterns"](https://infoscience.epfl.ch/record/98468/files/MatchingObjectsWithPatterns-TR.pdf) (see section 4) by Emir, Odersky and Williams (January 2007).
58
+
Sometimes, the number of sub-values is fixed and we would like to return a sequence. For this reason, you can also define patterns through `unapplySeq` which returns `Option[Seq[T]]` This mechanism is used for instance in pattern `case List(x1, ..., xn)`.
0 commit comments