I am at the early stages of learning Scala and I've noticed different ways to declare methods.
I've established that not using an equals sign makes the method a void method (returning a Unit
instead of a value), and using an equals sign returns the actual value so
def product(x: Int, y: Int) {
x*y
}
will return ()
(Unit), but
def product(x: Int, y: Int) = {
x*y
}
will return the product of the two arguments(x*y
)
I've noticed a third way of declaring methods - with a colon. Here is an example
def isEqual(x: Any): Boolean
How does this differ from the =
notation? And in what situations will it be best to use this way instead?
Scala doesn't allow us to define an anonymous method. We can define a method's list of parameters in parentheses after its name. After the parameters list, we can provide a return type for the method with the leading colon sign. We then define a method's body after the equals sign.
=> is the "function arrow". It is used both in function type signatures as well as anonymous function terms. () => Unit is a shorthand for Function0[Unit] , which is the type of functions which take no arguments and return nothing useful (like void in other languages).
Scala functions are first class values. Difference between Scala Functions & Methods: Function is a object which can be stored in a variable. But a method always belongs to a class which has a name, signature bytecode etc. Basically, you can say a method is a function which is a member of some object.
A Scala method is a part of a class which has a name, a signature, optionally some annotations, and some bytecode where as a function in Scala is a complete object which can be assigned to a variable. In other words, a function, which is defined as a member of some object, is called a method.
When you use colon (and use equal) you explicitly define return type of method.
// method return Boolean value
def m(a : Int) : Boolean = a > 0
When you don't use colon and use equal you allow scala compiler inferring return type itself.
// method has return type of last expression (Boolean)
def m(a : Int) = a > 0
When you use neither colon nor equal your method has return type of Unit class.
// method has Unit return type
def m(a : Int){
a > 0
}
Others have perfectly explained the differences between the different declarations:
def foo: Boolean = true // explicitly declare the return type
and
def foo = true // let the compiler to implicitly infer Boolean
That being said, I have to warn you against
def foo { }
This is called procedure-syntax, and you should never use it, as it's has been already deprecated (since Oct 29, 2013), although you'll get a deprecation warning only under the -Xfuture
flag.
Whenever you have to declare a method returning Unit
(which you should avoid as much as possible, since it means you're relying on side-effects), use the following syntax
def foo: Unit = { }
Also, as a personal advice, explicitly annotating return types makes your code often more readable and helps you in catching errors early. You know what the function should return, so explicitly annotating the type allows the compiler to check that the implementation returns an appropriate value, right at the declaration position (if you use the function you will catch an error eventually, but perhaps far from where the error really is).
Also, when declaring an abstract member, you'd better also annotate the types
trait {
def foo
}
is legal, but the type of foo
is automatically inferred to be Unit
, which almost never what you want.
Instead, do
trait {
def foo: Boolean
}
if you don't want the return type then you used
scala> def product(x: Int, y: Int) { //in lack of = it explicit uses Unit
| x*y
| }
product: (x: Int, y: Int)Unit
//equivalent to below
scala> def product(x: Int, y: Int):Unit={
| x*y
| }
product: (x: Int, y: Int)Unit
and when you write
scala> def product(x: Int, y: Int) = { //here it explicit detect return type
| x*y
| }
product: (x: Int, y: Int)Int
//equivalent to below
scala> def product(x: Int, y: Int):Int = {
| return x*y
| }
product: (x: Int, y: Int)Int
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With