I am not too sure why x
can't be converted into a number?
Tuple indexing only works with literal numbers. You cannot do dynamic tuple indexing.
Also, if you're posting code examples, you should post them as text. Posting a screenshot just makes it harder for people to help you.
And to add to what @DanielKeep was saying, it's because it's indexed statically at compilation time instead of at runtime. If you want to use dynamic indexing, try using either a slice, Vec
or [u8; 3]
.
fn main()
{
struct Colour(u8, u8, u8);
let green = Colour(0, 255, 0);
for x in 0..3
{
println!("{}", green.x); // Error over here
}
}
So what is a literal number and a dynamic number then?
Is it faster to use dynamic numbers or static numbers during runtime?
Which one of these is the best to use?
Tuples are anonymous structs with anonomous fields, so the numbers are just field names, not normal numbers. So using a variable to access it won't work. Don't use them as an aggregate data structure.
Well, I think that it'd be about the same, but if you're looking at the minor details, the memory address for tuple indexing is precalculated while dynamic indexing is done by multiplying the size of the struct by the index. Also note that the three types I mentioned must all contain the same type unlike tuples.
For flexibility? A Vec<T>
, because it can deref to a [T]
and a sized array can be constructed by just indexing the vec like so:
let data = vec![0, 255, 0];
let array = [data[0], data[1], data[2]];
In this case I would use a [u8; 3]
because he is modelling a color.
Doesn't the variable just get converted to a number though? For example if I typed green.0
that would work, right? But if I typed green.x
and x
stores the value 0
, what is the difference between the value 0
stored in x
and 0
when used to index the tupal, like the value is exactly the same though??
Is it possible to force Vec to be all u8?
Because the place the code will go to to get the value you want is predetermined in a tuple while it is calculated at runtime in an array/vec/slice/etc.
I see, thanks for clearing that up.
Well a Vec<T>
can only contain T
s, so by saying it's a Vec<u8>
it can only contain u8
s
Supports
let px = RGBA8::new(1,2,3,4);
for i in px.as_slice() {
}
and many others.
Because of the case of a tuple with mixed types.
let x : (u8, u32, f32); = (0, 1, 1.0);
let index = 1;
let test_1 = x.1;
let test_2 = x.index;
In this case of test_2
, Rust would have to figure out the offset of the u32
, and then get the value at runtime, and more importantly, what is the type of test_2
. Whereas in test_1
Rust would figure out the offset at compile time, and there is a well defined type of test_1
.
So there would be a performance penalty. But more importantly, there is now a syntax ambiguity. does x.y
mean access field y
on x
, or calculate the offset of the y
th field on x
, and access that field? What if the fields are different types? There is quite a bit to think about and some ambiguity about the dot operator, something there should be absolutely no ambiguity about.
0
is a literal number. 3
is a literal number. A literal number is any number written literally as a number right there in the source. Not a variable, not a constant, not the result of an expression, just an actual number.
Trying to access tuple index using runtime number is literally same as to access struct field using runtime string field name. Tuples are just struct whose field names are automatically generated by compiler, and those field names happens to looks like integer literal.
.0
on a tuple and [0]
on an array are exactly the same thing once the optimizer runs. There's no performance difference.
Because you have something homogeneous, I encourage you to use an array. Especially for Copy things where borrowck differences are less important. (Not to mention that slice patterns are stable now, removing another difference.)