how to declare an array with explicit type in vlang?

159 views Asked by At

I am trying to declare an array like below

arr := [
  [0, 0],
  [1, 2],
  [2, 4],
]

// type: [][]int

but the type I am getting from the inference is [][]int, instead I want to declare [][]float32. When I tried the below syntax I got [][]f64.

arr := [
  [0.0, 0],
  [1.0, 2],
  [2.0, 4],
]

// type: [][]f64

what I want is a simple way like the below, we can declare in c

float arr[][2] = {
    {0, 0},
    {1, 2},
    {2, 4}
};

// type: f32

I was reading the v docs but couldn't find any information about how to give explicit type in the array.

2

There are 2 answers

0
Larpon On

V will "automagically" infer types by the type of the first element:

arr := [
    [f32(0), 0],
    [f32(1), 2],
    [f32(2), 4],
]
println('${typeof(arr)}')
println(arr)
// -> [][]f32
// -> [[0.0, 0.0], [1.0, 2.0], [2.0, 4.0]]

Another, shorter, way is to initialize it first, but then you will not have initial values:

a := [][]f32{len: 3, init: []f32{len: 2}}
println('${typeof(a)}')
println(a)
// -> [][]f32
// -> [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]
0
Hungry Blue Dev On

Hey thanks for trying out V!

From the documentation, you can initialise an array either the way you are doing: explicitly listing all elements, or pre-allocate with initial values using a dedicated syntax. Let's see how we can get the code to work both ways.

Explicit Declaration

arr := [
    [f32(0), 0],
    [f32(1), 2],
    [f32(2), 4],
]
println(arr)
println(typeof(arr).name)

Output:

> v run example.v
[[0.0, 0.0], [1.0, 2.0], [2.0, 4.0]]
[][]f32

When you declare an array with all the elements listed, you only need to specify the type of the first element. The types for the rest can be inferred, assuming they are primitive. If you omit the f32() typecast for the rest of the arrays, the internal type inference assumes the arrays are []int or []f64 which leads to compilation errors.

It does make sense to allow hinting the compiler that we will be working with f32s exclusively so that we won't have to cast the first element of every sub-array. Consider making a feature request on Github.

Initialisation Syntax

arr := [][]f32{len: 3, init: []f32{len: 2, init: (index + 1)}}
println(arr)
println(typeof(arr).name)

Output:

> v run example.v
[[1.0, 2.0], [1.0, 2.0], [1.0, 2.0]]
[][]f32

This example shows the struct-like method of declaring and initialising an array. Here, we specify up-front that we want a 2D [][]f32 array. Inside, we specify that the nested arrays are 1D []f32 arrays. We make use of the index variable for the init expression. I suggest keeping the array mutable using mut arr := ... if you want to modify the elements later.

Instead of using len you might also use cap to specify a capacity. Then you might use a for loop to push arrays to the outer array using the << operator. See this section for more examples.