Slices in Julia

# Vectors are an important data type in Julia, giving
# a more powerful interface to sequences than arrays.

# Unlike arrays, vectors are typed only by the
# elements they contain (not the number of elements).
# An uninitialized vector equals to an empty vector and has
# length 0.
s = Vector{String}()
println("uninit: ", s, " ", isempty(s), " ", length(s) == 0)

# To create an empty vector with non-zero length, use
# the `Vector` constructor. Here we make a vector of
# `String`s of length `3` (initially filled with empty strings).
s = Vector{String}(undef, 3)
println("emp: ", s, " len: ", length(s), " cap: ", length(s))

# We can set and get just like with arrays.
s[1] = "a"
s[2] = "b"
s[3] = "c"
println("set: ", s)
println("get: ", s[3])

# `length` returns the length of the vector as expected.
println("len: ", length(s))

# In addition to these basic operations, vectors
# support several more that make them richer than
# arrays. One is the `push!` function, which
# adds one or more new values to the end of a vector.
push!(s, "d")
push!(s, "e", "f")
println("push: ", s)

# Vectors can also be `copy`'d. Here we create a
# new vector `c` and copy into `c` from `s`.
c = copy(s)
println("cpy: ", c)

# Vectors support a "slice" operator with the syntax
# `vector[start:end]`. For example, this gets a slice
# of the elements `s[3]`, `s[4]`, and `s[5]`.
l = s[3:5]
println("sl1: ", l)

# This slices up to (but excluding) `s[5]`.
l = s[1:5]
println("sl2: ", l)

# And this slices up from (and including) `s[3]`.
l = s[3:end]
println("sl3: ", l)

# We can declare and initialize a variable for vector
# in a single line as well.
t = ["g", "h", "i"]
println("dcl: ", t)

# Julia has built-in comparison for vectors.
t2 = ["g", "h", "i"]
if t == t2
    println("t == t2")
end

# Vectors can be composed into multi-dimensional data
# structures. The length of the inner vectors can
# vary, unlike with multi-dimensional arrays.
twoD = Vector{Vector{Int}}(undef, 3)
for i in 1:3
    innerLen = i
    twoD[i] = Vector{Int}(undef, innerLen)
    for j in 1:innerLen
        twoD[i][j] = i + j - 1
    end
end
println("2d: ", twoD)

Note that while vectors are different types than arrays, they are rendered similarly by println.

When you run this Julia script, you should see output similar to the following:

uninit: String[] true true
emp: ["", "", ""] len: 3 cap: 3
set: ["a", "b", "c"]
get: c
len: 3
push: ["a", "b", "c", "d", "e", "f"]
cpy: ["a", "b", "c", "d", "e", "f"]
sl1: ["c", "d", "e"]
sl2: ["a", "b", "c", "d", "e"]
sl3: ["c", "d", "e", "f"]
dcl: ["g", "h", "i"]
t == t2
2d: [[1], [2, 3], [3, 4, 5]]

In Julia, vectors are similar to slices in many ways. They are dynamic, resizable arrays. The main differences in this translation are:

  1. We use Vector{T} instead of []T for type declarations.
  2. Indexing starts at 1 in Julia, not 0.
  3. We use push! instead of append to add elements to a vector.
  4. Julia has built-in vector equality comparison, so we don’t need a separate function for that.
  5. Julia doesn’t have a separate cap function; the capacity of a vector is always equal to its length.

The concepts of slicing, multi-dimensional vectors, and vector operations are very similar between Go and Julia.