Reputation: 5121
This is the behaviour I tried:
struct Matrix(f32, f32, f32, f32);
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
matrix.len(); // expected `4`
which produces the error:
error[E0599]: no method named `len` found for type `&tuples::Matrix` in the current scope
--> src/tuples.rs:19:44
|
19 | println!("matrix length: {}", self.len());
| ^^^
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following traits define an item `len`, perhaps you need to implement one of them:
candidate #1: `std::iter::ExactSizeIterator`
candidate #2: `core::slice::SliceExt`
candidate #3: `core::str::StrExt`
std::iter::ExactSizeIterator
looks like a good candidate, but I still don't know how to implement it
Whilst trying to reverse Matrix
, I realized that instead of dryly listing the reverse indexes of the matrix like so:
fn reverse(matrix: Matrix) -> Matrix {
return Matrix(matrix.3, matrix.2, matrix.1, matrix.0)
}
I could perhaps iterate over the Matrix
in reverse order. I saw How to iterate or map over tuples? and thought that it was complex. If one were able to get the length of the tuple, one could solve the question "How to iterate or map over tuples?" with a simpler solution. Obviously, I could just use '4' as the length, but what if I weren't using a struct but rather a tuple of an unknown length.
Upvotes: 5
Views: 3473
Reputation: 1
In rust you cant iterate or ask for tuple length. Tuples are implemented in a similar way to struct (anonymous struct if you like). Considering tuple/struct with different types, what is it's length ?
Upvotes: -1
Reputation: 161607
There are a few ways to approach this question. I'll try to expand as I go.
matrix.len(); // expected `4`
You've defined your own Matrix
datatype. With no additional logic, it's entirely up to you to define this, e.g.
impl Matrix {
fn len(&self) -> usize {
4
}
}
Personally I think your reverse
function is fine as-is, because it's important to balance DRY with readability, and also differentiate repetition of code with repetition of logic.
The other piece here is that having the length on its own doesn't offer much here. matrix.0
is explicit syntax in Rust, but there's no way to actually use the length to do anything about that. matrix[i]
is not an operation you have implemented on your datatype. You can potentially implement that or Iterator
for this type, but that doesn't seem like what you'd actually want here. An iterator is a stream of consistent items, but your matrix items have explicit meaning based on their indices that would kind of lose their meaning in the context of an iterator.
I'll also add that you can trim down your reverse
using destructuring assignment and auto-return, via
fn reverse(matrix: Matrix) -> Matrix {
let Matrix(a, b, c, d) = matrix;
Matrix(d, c, b, a)
}
Upvotes: 2