This question already has answers here:
What is the apply function in Scala?
(7 answers)
Closed 1 year ago.
I have below "apply" function, what does apply function do? can you please explain for me?
def apply[K,V](m1:Map[K,V], m2:Map[K,V], merge: (V,V) => V): Map[K,V] =
combine(m1,m2,merge)
The apply function in companion objects and classes has a special meaning in that if an object/class is instantiated without specifying the function, it is the one which is run.
E.g.
object DDF { def apply(text :String) = println(s"got $text") }
DDF("text") // object called like function. function actually called is apply(String) here.
In your example, the apply function merely calls combine. so X(a,b,c) is the same as X.combine(a,b,c).
The technique is how we have achieve multiple constructors on classes too.
Related
This question already has answers here:
How to pass Scala array into Scala vararg method?
(3 answers)
Closed 4 years ago.
Is there a way to declare a variable of type String* in scala? As in a variable number of arguments? The issue is that when I want to test a series of methods that takes in a String* as a parameter and don't want to just replicate the values I pass in every test. I know that I can change the functions to take in a collection of String like Array or Seq, but I wanted to know if there was a way to do it without changing the parameter types
Varargs notation:
def foo(ss :String*) = {
//ss is Seq[String], you can ss.map(), ss.length, etc.
}
usage:
foo()
foo("this", "that")
foo("abc", "abd", "abx")
val someList = List("another" , "collection", "of", "strings")
foo(someList :_*) // turn a collection into individual varargs parameters
This question already has answers here:
What is the eta expansion in Scala?
(2 answers)
Closed 4 years ago.
New to Scala, have searched far and wide for clarification on some ScalaMock syntax. As per this guide, I keep seeing the following general testing pattern:
(myClass.myMethod _).expects()
What exactly is happening here? What function does the class/method/space/underscore serve? How does the compiler treat this?
The appended _ forces the conversion of a method into a function.
To understand why this is necessary, let's try to re-build a tiny piece of Scalamock, namely the expects method. The expects method seems to be invoked on methods of mocked objects. But methods / functions do not have an expects method to begin with. Therefore, we have to use the "pimp my library"-pattern to attach the method expects to functions. We could do something like this:
implicit class ExpectsOp[A, B](f: A => B) {
def expects(a: A): Unit = println("it compiles, ship it...")
}
Now let's define a class Bar with method baz:
class Bar {
def baz(i: Int): Int = i * i
}
and also an instance of Bar:
val bar = new Bar
Let's see what happens if you try to invoke expects on bar.baz:
(bar.baz).expects(42)
error: missing argument list for method baz in class Bar
Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing baz _ or baz(_) instead of baz.
So, it doesn't work without explicit conversion into a function, and we have to enforce this conversion by appending an _:
(bar.baz _).expects(42) // prints: "it compiles, ship it..."
This question already has an answer here:
Difference between function with parentheses and without [duplicate]
(1 answer)
Closed 6 years ago.
I was learning about scala methods and I created two code examples which are somewhat similar in nature, but confused on calling them.
Method #1
def someTestMethod = {
println("Inside a test method")
}
This resorts to a Unit type since it does not return anything.
Method #2
def anotherTestMethod() = {
println("Inside a test method")
}
This resorts to Unit as well, but with a curly brace () added.
What is the difference between the two methods, notice that if I call the first method like someTestMethod(), the scala shell/compiler says
error: Unit does not take parameters, but works well if I call like someTestMethod without the braces.
Also, the second method seems fool proof, in the sense that it can be called either way anotherTestMethod or anotherTestMethod(), why is it so?
When you don't want to pass any parameter to the method, use the first one.
If you want to pass some pass parameters, use the second one with brackets and pass some parameters and use it inside method.
For example:
def someTestMethod1(count : Int) = {
println("Inside a test method"+count)
}
someTestMethod1(10)
This question already has answers here:
How to check constructor arguments and throw an exception or make an assertion in a default constructor in Scala?
(2 answers)
Closed 7 years ago.
Suppose that I have the following class defined in Scala:
class ClassA(val n: Int) {
...
}
I want to limit this class instances to only those that have n between 5 to 10 using Factory Pattern. For example, In case I write something like:
val a = new ClassA(11)
This raises an exception with an appropriate error message, or at least it returns null or something. How can I achieve this behaviour?
Update:
It is possible to achieve this in java with Factory pattern.
Update2:
This questions seems to be answered here, notably with a verbose title though. I tweak the title and content to save the question being deleted, because of two reasons: 1) The example in this one is concise, 2) the provided answer by #Chris Martin explains briefly the way Factory pattern can be reached in Scala by Using Companion Objects.
The conventional way to write a factory in Scala is to define an apply method on the companion object.
Here's an example using Either (because null is never/rarely used in Scala, and exceptions are ugly):
class A private (n: Int) {
override def toString = s"A($n)"
}
object A {
def apply(n: Int): Either[String, A] =
if (n < 5) Left("Too small")
else if (n > 10) Left("Too large")
else Right(new A(n))
}
A(4) // Left(Too small)
A(5) // Right(A(5))
A(11) // Left(Too large)
This is the essentially the same as the Java example you referenced. The A constructor is private, so the class can only be instantiated via the factory method.
This question already has an answer here:
using variable length argument in scala
(1 answer)
Closed 7 years ago.
I have an interface
object Leaf {
def apply(keys: Int*): Leaf = {
new Leaf(keys)
}
}
where Leaf class is defined as follows:
class Leaf(keys: Seq[Int]) extends Node(true, keys, Seq())
Is this possible to pass a Sequence as a keys parameter? Of course I could create second varargs method, but i wonder if there is a method which converts a Sequence into varargs paremeter.
Yes, and I think you mean varargs not varchar :)
Leaf(sequence: _*)