Slices in Scala

Slices are an important data structure in many programming languages, providing a more flexible interface to sequences than arrays. In Scala, we can achieve similar functionality using various collection types, primarily ArrayBuffer for mutable sequences and Vector for immutable ones.

import scala.collection.mutable.ArrayBuffer

object Slices {
  def main(args: Array[String]): Unit = {
    // In Scala, we can use ArrayBuffer for a mutable sequence similar to Go's slices
    var s = ArrayBuffer.empty[String]
    println(s"uninit: $s, ${s.isEmpty}, ${s.length == 0}")

    // To create an empty ArrayBuffer with non-zero length, we can use fill
    s = ArrayBuffer.fill(3)("")
    println(s"emp: $s, len: ${s.length}")

    // We can set and get just like with arrays
    s(0) = "a"
    s(1) = "b"
    s(2) = "c"
    println(s"set: $s")
    println(s"get: ${s(2)}")

    // length returns the length of the ArrayBuffer as expected
    println(s"len: ${s.length}")

    // We can append elements to an ArrayBuffer
    s += "d"
    s ++= Seq("e", "f")
    println(s"apd: $s")

    // We can copy ArrayBuffers
    val c = s.clone()
    println(s"cpy: $c")

    // Scala provides slice operations on collections
    val l = s.slice(2, 5)
    println(s"sl1: $l")

    // This slices up to (but excluding) index 5
    val l2 = s.take(5)
    println(s"sl2: $l2")

    // And this slices from index 2 to the end
    val l3 = s.drop(2)
    println(s"sl3: $l3")

    // We can declare and initialize a sequence in a single line
    val t = Vector("g", "h", "i")
    println(s"dcl: $t")

    // Scala provides many utility functions for collections
    val t2 = Vector("g", "h", "i")
    if (t == t2) {
      println("t == t2")
    }

    // We can create multi-dimensional structures
    val twoD = Array.ofDim[Int](3, 3)
    for (i <- 0 until 3) {
      for (j <- 0 to i) {
        twoD(i)(j) = i + j
      }
    }
    println(s"2d: ${twoD.map(_.mkString("[", ",", "]")).mkString("[", ", ", "]")}")
  }
}

To run this Scala program, you would typically use the Scala Build Tool (sbt) or compile and run it directly with the Scala compiler:

$ scalac Slices.scala
$ scala Slices
uninit: ArrayBuffer(), true, true
emp: ArrayBuffer(, , ), len: 3
set: ArrayBuffer(a, b, c)
get: c
len: 3
apd: ArrayBuffer(a, b, c, d, e, f)
cpy: ArrayBuffer(a, b, c, d, e, f)
sl1: ArrayBuffer(c, d, e)
sl2: ArrayBuffer(a, b, c, d, e)
sl3: ArrayBuffer(c, d, e, f)
dcl: Vector(g, h, i)
t == t2
2d: [[0], [1,2], [2,3,4]]

Note that while Scala doesn’t have a direct equivalent to Go’s slices, the ArrayBuffer and other collection types in Scala provide similar functionality with a rich set of operations. Scala’s collections are more diverse and offer both mutable and immutable variants, allowing for different programming paradigms.