Description
Proposal
Problem statement
Boxed slices are space-saving alternatives to Vec
and String
when the ability to grow the allocation is not required. To make them easier replacements, it would be ideal for Box<[T]>
and Box<str>
to provide all the functionality of Vec<T>
and String
that doesn't require resizing.
One functionality gap is that String
implements FromIterator
(for 6 types of Iterator
item), but Box<str>
doesn't. There's already an analogous implementation for Box<[T]>
: FromIterator
is implemented for Box<[T]>
by using Vec<T>
's FromIterator
implementation and then calling into_boxed_slice()
to convert to a Box<[T]>
. The proposal is to do the same thing for Box<str>
: provide the same FromIterator
implementations that String
has, which can be implemented by collecting into a String
and then calling into_boxed_str()
.
Additionally, impl FromIterator<Box<str>> for String
and impl Extend<Box<str>> for String
can be generalized to allow boxed strings with allocators other than Global
. The implementations already copy the bytes to the String
's allocation, so they work for Box<str, A>
with any A: Allocator
.
Motivation, use-cases
The existing impl<I> FromIterator<I> for Box<[I]>
makes it convenient to collect an iterator into a boxed slice, for example:
let squares: Box<_> = (1..10).map(|x| x * x).collect();
Box<str>
is an even more useful alternative to String
than Box<[T]>
is for Vec<T>
, as strings are often immutable. The existing FromIterator<char>
implementation for String
makes it easy, for example, to reverse the characters in a string:
fn reverse(s: &str) -> String {
s.chars().rev().collect()
}
However, returning a Box<str>
requires a much more verbose implementation:
fn reverse(s: &str) -> Box<str> {
s.chars().rev().collect::<String>().into_boxed_str()
}
Providing a FromIterator
implementation for Box<str>
would allow for the same implementation as for String
.
Solution sketches
An implementation is available here: rust-lang/rust#99969
The same FromIterator
implementations as for String
are added for Box<str>
. The implementations are straightforward, using String
's FromIterator
implementation and then calling into_boxed_str()
to remove the excess capacity, analogous to impl<I> FromIterator<I> for Box<[I]>
.
One other possibility is to extend the FromIterator
implementations to Box<str, A>
for all A: Allocator
. But this is not currently done for Box<[T], A>
or Vec<T, A>
, so I opted to do the same and only add implementations for Box<str>
.
Links and related work
rust-lang
PR: rust-lang/rust#99969
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.