5

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?

0

2 Answers 2

11

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Worked fine. I'm a little confused as to why I need to put static if string literals always have a static lifetime.
Lifetimes are part of the type, and types need to be completely specified for function signatures in rust. The is something called lifetime elision which simplifies specific cases, but Rust only rarely used such deduced properties. In this case elision does not apply because there is no lifetime use for the input arguments (as there are none).
@camccar No the duplicate say an equivalent of this answer.
I don't see anywhere that says prepend with static.
2

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].

2 Comments

Curios, why can't I have values of type str?
@camccar it's because the str type doesn't have a size. Therefore, its size can't be calculated for pre-allocating memory on the stack. On the other hand, a reference does have a size (It's basically just a pointer)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.