string
import std::collections::string; · source
String<A>
type struct String<A = GlobalAlloc> {
buffer: RawBuffer<u8, A>;
length: u64;
static new() -> String;
static new_in(alloc: A) -> String<A>;
static with_capacity(capacity: u64) -> String;
static try_with_capacity_in(capacity: u64, alloc: A) -> Result<String<A>, AllocError>;
static from_str(source: Str) -> String;
![implicit]
static from_string(text: string) -> String;
static with_null(source: Str) -> String;
static from<T>(item: T) -> String;
push<T>(mut &this, item: T) -> void;
try_push<T>(mut &this, item: T) -> Result<(), AllocError>;
push_byte(mut &this, byte: u8) -> void;
try_push_byte(mut &this, byte: u8) -> Result<(), AllocError>;
clear(mut &this) -> void;
length(&this) -> u64;
capacity(&this) -> u64;
is_empty(&this) -> boolean;
as_str(&this) -> Str;
as_bytes(&this) -> Slice<u8>;
as_ptr(&this) -> u8*;
as_cstr(mut &this) -> u8*;
into_raw(mut this) -> string;
starts_with(&this, prefix: &Str) -> boolean;
ends_with(&this, suffix: &Str) -> boolean;
find(&this, needle: &Str) -> Option<u64>;
contains(&this, needle: &Str) -> boolean;
trim(&this) -> Str;
trim_start(&this) -> Str;
trim_end(&this) -> Str;
to_ascii_uppercase(&this) -> String;
to_ascii_lowercase(&this) -> String;
split(&this, sep: &Str) -> SplitIter;
chars(&this) -> Chars;
char_indices(&this) -> CharIndices;
truncate(mut &this, new_length: u64) -> void;
reserve(mut &this, additional: u64) -> Result<(), AllocError>;
reserve_exact(mut &this, additional: u64) -> Result<(), AllocError>;
shrink_to_fit(mut &this) -> void;
}
The owned, growable companion to Str: a heap byte buffer plus a length. No NUL terminator, no encoding assumptions beyond "the bytes are valid UTF-8". The first allocation reserves 8 bytes.
Constructing
| Constructor | Notes |
|---|---|
new() / new_in(alloc) | Empty. No heap storage until the first push. |
with_capacity(capacity) | Preallocated. try_with_capacity_in is the fallible form. |
from_str(source: Str) | Copy a borrowed view into owned storage. |
from_string(text: string) | Copy a C string. Marked ![implicit], so mut s: String = "text" and println("text") both route through it. |
from<T>(item) | The general constructor — same dispatch as push. |
with_null(source: Str) | Owned copy that keeps a trailing NUL for the FFI boundary. |
Appending
push<T> appends item as its text representation, dispatched at compile time through static match (T) — no runtime cost and no trait bound, because the available arms are the accepted types:
String,Str, andstring— the UTF-8 bytes verbatim (astring's terminating NUL is not copied).- Every primitive integer,
usize, andisize— its decimal text.s.push(65 as u8)appends"65". f32andf64— theirDisplaytext.boolean—"true"or"false".
Anything else is a compile error; the static match has no _ arm.
mut s: String = String::new();
s.push("count: ");
s.push(42); // "count: 42"
s.push_byte(0x0A); // a raw newline byte
push_byte appends a single raw byte rather than its decimal text — for NUL terminators, control characters, and binary buffers. Keeping the result valid UTF-8 is your responsibility. Both have try_ forms returning Result<(), AllocError> instead of panicking.
Reading and borrowing
length(), capacity(), is_empty(), as_str() -> Str, as_bytes() -> Slice<u8>, as_ptr() -> u8*, plus clear(), truncate(new_length), reserve, reserve_exact, and shrink_to_fit.
The Str conveniences are forwarded so you don't write s.as_str().starts_with(...) everywhere: starts_with, ends_with, find, contains, trim, trim_start, trim_end, to_ascii_uppercase, to_ascii_lowercase, split, chars, and char_indices. Everything they return borrows this string's buffer and is valid only while it lives unmutated.
Crossing into C
A String built by push carries no trailing NUL, so as_ptr() alone is not a valid C string. Two methods bridge the gap:
as_cstr(mut &this) -> u8*borrows the buffer as a NUL-terminated C string. It writes the terminator at indexlength— reserving one spare byte if the buffer is full — without changing the logical length. Idempotent and zero-allocation once the spare byte exists. The pointer is valid until the next mutating call and must not be freed by the caller.into_raw(mut this) -> stringconsumes the string, appends a terminator, and hands back the raw buffer, leaking the allocation so the caller owns the bytes outright.
As in C, an interior NUL ends the string early; the bytes are not otherwise validated.
Trait implementations
implement<A> trait Eq for struct String<A>
where A: Allocator
implement<A> trait Hash for struct String<A>
where A: Allocator
implement<A> trait Ord for struct String<A>
where A: Allocator
implement<A> trait Drop for struct String<A>
where A: Allocator
implement trait Clone for struct String<GlobalAlloc>
implement trait Default for struct String<GlobalAlloc>
implement<A> trait Display for struct String<A>
where A: Allocator // std::fmt::display
implement trait Debug for struct String<GlobalAlloc> // std::fmt::display
implement trait FmtWrite for struct String<GlobalAlloc> // std::fmt::write
Eq, Ord, and Hash agree with Str's, so a String and a Str holding the same bytes hash and compare identically. FmtWrite is what lets a String be the sink of a Formatter — format_to_string is built on it.