How to initialize empty str?

Is it possible to initialize an empty str of a known length? I'm trying to write a parser. The output of each parsed message will be a 2x10 table, where each row has 2 str's of a known length, and I want to push characters into each str until it's full.

Should I use [char; N] instead?

Since I want to push characters in one at a time, should I implement my own struct to hold an index for the next insert?

It sounds like you should be using String here.

let mut s = String::new(); // starts empty; you could use `String::with_capacity`
                           // here since you know the full size in advance
s.push('~');

Vec<u8> would be another possibility, if all your characters are ASCII and you need indexing.

For a string with a short compile-time-known upper bound in length, you could use the arrayvec crateʼs ArrayString<CAP> type. This avoids heap allocations. Note that the capacity CAP describes the number of bytes in UTF-8; non-ascii chars can take up to 4 bytes. It basically stores the string in a contained [MaybeUninit<u8>; CAP].

2 Likes

Ya, I have a working implementation using String, but I want to rewrite it to avoid heap allocation.

In that case @steffahn's suggestion is the way to go.

2 Likes

heapless::String is also an option.

1 Like

You can also just use an [u8; N] and use str::from_utf8 at the end.

3 Likes

Alice, if I use [u8; N], do I have to implement push myself? I assume that means storing an index value so it knows where to insert the pushed character.

Yes

You can also use iterator if you don't want to implement push yourself.

let input = vec![1,2,3,4,5];
let mut output = [0;5];
input.iter().zip(output.iter_mut())
    for_each(|(i,o)| *o = *i);
assert_eq!(output, [1,2,3,4,5]);

But if you do so you should be sure that input size is equal to output size otherwise you can miss one input element:

// 5 is not read
let input = vec![1,2,3,4,5];
let mut output = [0;4];
input.iter().zip(output.iter_mut())
    .for_each(|(i,o)| *o = *i);
assert_eq!(output, [1,2,3,4]);

or have some output values that are not properly set.

// Number of input values is too small
let input = vec![1,2,3,4,5];
let mut output = [0;6];
input.iter().zip(output.iter_mut())
   .for_each(|(i,o)| *o = *i);
assert_eq!(output, [1,2,3,4,5,0]);
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.