`&[f64]` cannot be indexed by `usize`

I'm unclear as to why the following code doesn't compile.

use std::collections::HashMap;
use core::ops::Index;

fn main() {
    let t: HashMap<String, Vec<f64>> = HashMap::new();
    let r= execute(&t);
    let t: HashMap<String, &[f64]> = HashMap::new();
    let r = execute(&t);
}

fn execute<S, V>(params: &HashMap<S, V>) -> Vec<f64>
where
    S: Into<String>,
    V: Index<usize, Output = f64>,
{
    Vec::new()
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0277]: the type `&[f64]` cannot be indexed by `usize`
  --> src/main.rs:8:21
   |
8  |     let r = execute(&t);
   |                     -^
   |                     |
   |                     `&[f64]` cannot be indexed by `usize`
   |                     help: consider removing 1 leading `&`-references
...
11 | fn execute<S, V>(params: &HashMap<S, V>) -> Vec<f64>
   |    -------
...
14 |     V: Index<usize, Output = f64>,
   |        -------------------------- required by this bound in `execute`
   |
   = help: the trait `std::ops::Index<usize>` is not implemented for `&[f64]`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Anyone have some clarity they could provide me on why this error occurs? I'd like to keep the execute function generic enough to support both calls being made.

1 Like

Index trait is implemented for owned types (such as Vec<T> and [T]) but not for borrowed types (&[T]), because Index::index() borrows &self and does not consume the object.
So, you need to get owned type, and call Index::index() for that type.

If you want to accept &ArrayLikeType, you can use std::ops::Deref to make it generic over dereferences.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=750ab298161f24b9dd3958bea470d34f

BTW, HashMap<S, T> where S: Into<String> would be useless (because you cannot create value of S type)...
I guess you meant S: From<String> or something else.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.