Scala Operators

Scala provides rich operators, including arithmetic operators, relational operators, logical operators, and more. In Scala, operators are actually syntactic sugar for method calls.

Arithmetic Operators

object ArithmeticOperators {
  def main(args: Array[String]): Unit = {
    val a = 10
    val b = 3
    
    println(s"a + b = ${a + b}")  // Addition: 13
    println(s"a - b = ${a - b}")  // Subtraction: 7
    println(s"a * b = ${a * b}")  // Multiplication: 30
    println(s"a / b = ${a / b}")  // Division: 3
    println(s"a % b = ${a % b}")  // Modulus: 1
    
    // Floating-point operations
    val x = 10.0
    val y = 3.0
    println(s"x / y = ${x / y}")  // 3.3333333333333335
  }
}

Relational Operators

object RelationalOperators {
  def main(args: Array[String]): Unit = {
    val a = 10
    val b = 20
    
    println(s"a == b: ${a == b}")  // Equal: false
    println(s"a != b: ${a != b}")  // Not equal: true
    println(s"a > b: ${a > b}")    // Greater than: false
    println(s"a < b: ${a < b}")    // Less than: true
    println(s"a >= b: ${a >= b}")  // Greater than or equal: false
    println(s"a <= b: ${a <= b}")  // Less than or equal: true
  }
}

Logical Operators

object LogicalOperators {
  def main(args: Array[String]): Unit = {
    val a = true
    val b = false
    
    println(s"a && b: ${a && b}")  // Logical AND: false
    println(s"a || b: ${a || b}")  // Logical OR: true
    println(s"!a: ${!a}")          // Logical NOT: false
    
    // Short-circuit evaluation
    val x = 5
    val result1 = x > 0 && x < 10  // true
    val result2 = x < 0 || x > 3   // true
    
    println(s"result1: $result1")
    println(s"result2: $result2")
  }
}

Bitwise Operators

object BitwiseOperators {
  def main(args: Array[String]): Unit = {
    val a = 12  // Binary: 1100
    val b = 10  // Binary: 1010
    
    println(s"a & b = ${a & b}")   // Bitwise AND: 8 (1000)
    println(s"a | b = ${a | b}")   // Bitwise OR: 14 (1110)
    println(s"a ^ b = ${a ^ b}")   // Bitwise XOR: 6 (0110)
    println(s"~a = ${~a}")         // Bitwise NOT: -13
    println(s"a << 2 = ${a << 2}") // Left shift: 48 (110000)
    println(s"a >> 2 = ${a >> 2}") // Right shift: 3 (11)
  }
}

Assignment Operators

object AssignmentOperators {
  def main(args: Array[String]): Unit = {
    var a = 10
    
    a += 5   // a = a + 5
    println(s"a += 5: $a")  // 15
    
    a -= 3   // a = a - 3
    println(s"a -= 3: $a")  // 12
    
    a *= 2   // a = a * 2
    println(s"a *= 2: $a")  // 24
    
    a /= 4   // a = a / 4
    println(s"a /= 4: $a")  // 6
    
    a %= 4   // a = a % 4
    println(s"a %= 4: $a")  // 2
  }
}

Operator Precedence

Scala operator precedence from high to low:

  1. () [] .
  2. ! ~ unary + -
  3. * / %
  4. + -
  5. << >> >>>
  6. < <= > >=
  7. == !=
  8. &
  9. ^
  10. |
  11. &&
  12. ||
  13. = += -= and other assignment operators
object OperatorPrecedence {
  def main(args: Array[String]): Unit = {
    val result1 = 2 + 3 * 4      // 14 (not 20)
    val result2 = (2 + 3) * 4    // 20
    val result3 = 10 > 5 && 3 < 8 // true
    
    println(s"2 + 3 * 4 = $result1")
    println(s"(2 + 3) * 4 = $result2")
    println(s"10 > 5 && 3 < 8 = $result3")
  }
}

Custom Operators

In Scala, you can define custom operators:

class Vector2D(val x: Double, val y: Double) {
  // Define + operator
  def +(other: Vector2D): Vector2D = {
    new Vector2D(x + other.x, y + other.y)
  }
  
  // Define * operator (scalar multiplication)
  def *(scalar: Double): Vector2D = {
    new Vector2D(x * scalar, y * scalar)
  }
  
  // Define custom operator
  def ++(other: Vector2D): Vector2D = {
    new Vector2D(x + other.x * 2, y + other.y * 2)
  }
  
  override def toString: String = s"Vector2D($x, $y)"
}

object CustomOperators {
  def main(args: Array[String]): Unit = {
    val v1 = new Vector2D(1.0, 2.0)
    val v2 = new Vector2D(3.0, 4.0)
    
    val sum = v1 + v2
    val scaled = v1 * 2.0
    val custom = v1 ++ v2
    
    println(s"v1 + v2 = $sum")      // Vector2D(4.0, 6.0)
    println(s"v1 * 2.0 = $scaled")  // Vector2D(2.0, 4.0)
    println(s"v1 ++ v2 = $custom")  // Vector2D(7.0, 10.0)
  }
}

Method Call Form of Operators

In Scala, operators are actually syntactic sugar for method calls:

object OperatorMethods {
  def main(args: Array[String]): Unit = {
    val a = 10
    val b = 5
    
    // These two forms are equivalent
    println(a + b)        // Operator form
    println(a.+(b))       // Method call form
    
    println(a * b)        // Operator form
    println(a.*(b))       // Method call form
    
    // String operations
    val str1 = "Hello"
    val str2 = "World"
    
    println(str1 + " " + str2)           // Operator form
    println(str1.+(" ").+(str2))         // Method call form
  }
}

Special Operators

Option Type Operators

object OptionOperators {
  def main(args: Array[String]): Unit = {
    val opt1: Option[Int] = Some(10)
    val opt2: Option[Int] = None
    
    // getOrElse operator
    println(opt1.getOrElse(0))  // 10
    println(opt2.getOrElse(0))  // 0
    
    // map operator
    val doubled = opt1.map(_ * 2)
    println(doubled)  // Some(20)
    
    // flatMap operator
    val result = opt1.flatMap(x => Some(x + 5))
    println(result)   // Some(15)
  }
}

Collection Operators

object CollectionOperators {
  def main(args: Array[String]): Unit = {
    val list1 = List(1, 2, 3)
    val list2 = List(4, 5, 6)
    
    // :: operator (cons)
    val newList = 0 :: list1
    println(newList)  // List(0, 1, 2, 3)
    
    // ::: operator (concatenation)
    val combined = list1 ::: list2
    println(combined)  // List(1, 2, 3, 4, 5, 6)
    
    // ++ operator (concatenation)
    val concatenated = list1 ++ list2
    println(concatenated)  // List(1, 2, 3, 4, 5, 6)
  }
}

Practice Exercises

  1. Create a calculator class that implements basic arithmetic operations
  2. Define a complex number class that implements complex number addition and multiplication operators
  3. Use bitwise operators to implement a simple permission system
// Exercise 1: Calculator class
class Calculator {
  def add(a: Double, b: Double): Double = a + b
  def subtract(a: Double, b: Double): Double = a - b
  def multiply(a: Double, b: Double): Double = a * b
  def divide(a: Double, b: Double): Double = {
    if (b != 0) a / b
    else throw new IllegalArgumentException("Division by zero")
  }
}

// Exercise 2: Complex number class
class Complex(val real: Double, val imaginary: Double) {
  def +(other: Complex): Complex = {
    new Complex(real + other.real, imaginary + other.imaginary)
  }
  
  def *(other: Complex): Complex = {
    val newReal = real * other.real - imaginary * other.imaginary
    val newImaginary = real * other.imaginary + imaginary * other.real
    new Complex(newReal, newImaginary)
  }
  
  override def toString: String = {
    if (imaginary >= 0) s"$real + ${imaginary}i"
    else s"$real - ${-imaginary}i"
  }
}

// Exercise 3: Permission system
object PermissionSystem {
  val READ = 1    // 001
  val WRITE = 2   // 010
  val EXECUTE = 4 // 100
  
  def hasPermission(userPermissions: Int, requiredPermission: Int): Boolean = {
    (userPermissions & requiredPermission) == requiredPermission
  }
  
  def addPermission(userPermissions: Int, newPermission: Int): Int = {
    userPermissions | newPermission
  }
  
  def removePermission(userPermissions: Int, permissionToRemove: Int): Int = {
    userPermissions & ~permissionToRemove
  }
}

Operators are the foundation of Scala programming, mastering their use is essential for writing efficient and readable code.