Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala "def" method declaration: Colon vs equals

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?

like image 991
Marco Prins Avatar asked Oct 31 '14 08:10

Marco Prins


People also ask

How to define methods in Scala?

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.

What does => mean in Scala?

=> 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).

What is difference between function and method in Scala?

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.

What term would you use to define a function in Scala?

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.


3 Answers

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 
}
like image 185
Sergii Lagutin Avatar answered Sep 21 '22 14:09

Sergii Lagutin


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
}
like image 43
Gabriele Petronella Avatar answered Sep 22 '22 14:09

Gabriele Petronella


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
like image 24
Govind Singh Avatar answered Sep 22 '22 14:09

Govind Singh