None
instead of Some(null)
SC-A1002It is more idiomatic in scala to use Option
, i.e. Some
and None
instead of null
. Using Some(null)
instead of None
defeats the entire purpose of Option
. However, there might be certain scenarios where this is a legitimate approach, such as when dealing with Java-based libraries, to improve compatibility.
Carefully consider whether using Option
with null
is necessary before doing so.
Scala allows you to import entities from same package in separate statements. However, it is generally recommended that you group such imports together. Doing so makes the code more readable and easier to navigate.
find() [==/!=] None
with exists()
SC-R1009find()
allows you to look for elements in a collection that satisfy the provided condition/predicate. However, if you only need to determine whether elements matching your predicate exist, it is suggested that you directly use exists()
as it is slightly more efficient, readable, and easy to maintain.
filter().headOption
as find()
SC-P1006The scala analyzer has determined that this collection method chain can be simplified into a single call to find()
.
Use anonymous function when pattern matching element(s) rather than explicitly using the match
keyword when possible. This approach/syntax is cleaner, improves readability and is easy to comprehend.
Option.isDefined
, Option.isEmpty
or Option.nonEmpty
instead of Option.size
SC-R1004Scala's collections return either Some
or None
when retrieving elements depending on whether the requested element exists or not. Therefore, the idiomatic and right approach is to use Option.isDefined
, Option.isEmpty
or Option.nonEmpty
instead of Option.size
.
getOrElse()
on get()
SC-R1005get()
is used to index data structures such as Map
to retrieve values. Such structures also provide an additional method, getOrElse(),
that additionally allows you to provide a default value to use if the requested key is nonexistent. While get()
returns an Option[Type]
which may be Some(value)
or None
depending on whether the value exists, getOrElse()
will directly return a value of the correct type. If you need to supply a default value for nonexistent entries, it is more succinct and maintainable to use getOrElse()
on the collection itself instead of chaining getOrElse()
after get()
.
filter().isEmpty
with !exists()
SC-R1007filter()
allows you to select elements from your collection that satisfy the provided condition/predicate. In situations where you need to check if there are any elements satisfying your condition, it is suggested that you directly use !exists()
over filter().isEmpty
as the former is slightly more efficient, readable, and easy to maintain.
filter().size
with count()
SC-R1008filter()
allows you to select elements from your collection that satisfy the provided condition/predicate. In situations where you need to count the number of elements satisfying your condition, it is suggested that you directly use count()
over filter().size
as the former is slightly more efficient, readable and easy to maintain.
else
in else if
SC-R1015else
in else if
becomes redundant and can be dropped if the last statement under if's then
block is a return
statement. This improves code-readability and is easy to maintain.
for (i <- 0 to n - 1) is the common way to count from 0 till n. However, a more readable and appropriate way might be to adopt the 'until' keyword.
!isEmpty
with nonEmpty
SC-R1017Standard Scala structures provide with both isEmpty
and nonEmpty
methods. Thefore, replacing !isEmpty
with nonEmpty
makes the code slightly more readable and easier to comprehend.
Explicit boolean values on the RHS can be dropped in boolean comparisons.
.get
and then pattern matching over .contains
for a Map SC-R1021Scala's collections return either Some
or None
when retrieving elements depending on whether the requested element exists or not. It is therefore expected that when dealing with such collections, you use .get
and then use pattern-matching over other approaches such as .contains
.
.isEmpty
or .nonEmpty
when checking for empty String
s SC-R1022The String
type in Scala implements methods such as .isEmpty
and .nonEmpty
that you can use to check if a string is empty or not. While you can also use the comparison operators against an empty string, it is generally not considered as the right approach and is recommended that you use the said builtin methods.
if
condition as case's entry guard SC-R1023When pattern matching, case
s allow you to specify conditions that act as entry guards. Controller then enters into the body of these case
s only if these conditions satisfy. In scenarios where the body of a case
is wrapped in an if
condition, consider moving this if
condition and rewriting it as an entry guard. Doing so improves the overall readability of the code.
.isEmpty
or .nonEmpty
instead of .size
for List
s SC-R1025Scala's List
data structure is an immutable sequence of elements, implemented as a linked list. Because of this, methods such as .size
have a complexity of O(n). Repeatedly calling these methods can impact the performance of your application. Therefore, it is suggested that you use methods such as .isEmpty
or .nonEmpty
to check if a list is empty rather than relying on .size
.
Benchmarks -
val numsList = (1 to 1000000).toList
// 2713250ns
time {
numsList.size
}
val numsArray = (1 to 1000000).toBuffer
// 11750ns
time {
numsArray.size
}
==
or !=
to compare String
s SC-R1026Because comparison operators in languages like Java are usually used for reference equality checks, types such as String
implement a method called .equals
that allows you to check if two String
s are equal or not. However, Scala allows the user to perform value equality checks using the comparison operators as long as the object's class overrides the equals
method. It is suggested that you use comparison operators instead of the .equals
method when comparing 2 strings.
.dropRight
instead of .substring
when the lower-bound is 0 SC-R1027String.dropRight
provides a convenient way to remove an n
character suffix from a string. Consider rewriting .substring(0, ub)
as .dropRight(n)
; this is more succinct and clear.
isInstanceOf
SC-R1029.isInstanceOf[T]
allows you to check if an entity is of type T
or not and is handy when used correctly. There is a simpler and more idiomatic way to write such checks though - using pattern matching. The benefits of pattern matching aside; note that any approach that relies extensively on Any
, .isInstanceOf
and .asInstanceOf
defeats the language's type system and should be avoided.