How do I return a fixed size array of string literals from a function?

Viewed 4112

This function will work for the type i32, but for the type str:

fn getValues() -> [str; 2] {
    [
        "37107287533902102798797998220837590246510135740250",
        "46376937677490009712648124896970078050417018260538",
    ]
}

I get the error:

error[E0277]: the size for values of type `str` cannot be known at compilation time
 --> src/lib.rs:1:1
  |
1 | / fn getValues() -> [str; 2] {
2 | |     [
3 | |         "37107287533902102798797998220837590246510135740250",
4 | |         "46376937677490009712648124896970078050417018260538",
5 | |     ]
6 | | }
  | |_^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `str`
  = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
  = note: slice and array elements must have `Sized` type

This error makes me think I need to add the size but I did: a size of 2. What is Rust wanting?

2 Answers

str is the str primitive type, which is an unsized type, having some limitations -- you encountered one of them.

To solve your issue, instead of returning a plain str, you need to return a &str, a borrowed string slice. In this specific case you could even use &'static str, because string literals always have a static lifetime.

Also, because a primitive array is also a DST (dynamically sized type, another way to size unsized type), you need to specify the number of elements (which you did correctly).

So, the complete declaration would be fn getValues()-> [&'static str; 100].

If you do not know the size of the array at compile time, you might want to use a Vec, if you have some non-literal strings you likely want to use a String. That would look like

fn getValues() -> Vec<String> { vec!["shoten".into()] }

P.S.: Do not shy away from those heap-allocated, owned types -- they do make programming easier. Fighting with references and lifetimes is good style, but you don't need to do all that upfront, but instead optimize and refactor later.

It's saying str doesn't have a fixed size, not that the array doesn't. You can't have values of type str, you can only have them behind some kind of pointer.

Use [&'static str; 100].

Related