Sök…


Introduktion

Till skillnad från många andra språk har Rust två huvudsträngtyper: String (en heap-allokerad strängtyp) och &str (en lånad sträng, som inte använder extra minne). Att känna till skillnaden och när man ska använda var och en är avgörande för att förstå hur Rust fungerar.

Grundläggande strängmanipulation

fn main() {
    // Statically allocated string slice
    let hello = "Hello world";

    // This is equivalent to the previous one
    let hello_again: &'static str = "Hello world";

    // An empty String
    let mut string = String::new();

    // An empty String with a pre-allocated initial buffer
    let mut capacity = String::with_capacity(10);

    // Add a string slice to a String
    string.push_str("foo");

    // From a string slice to a String
    // Note: Prior to Rust 1.9.0 the to_owned method was faster
    // than to_string. Nowadays, they are equivalent.      
    let bar = "foo".to_owned();
    let qux = "foo".to_string();

    // The String::from method is another way to convert a
    // string slice to an owned String.
    let baz = String::from("foo");

    // Coerce a String into &str with &
    let baz: &str = &bar;
}

Obs: Både String::new och String::with_capacity skapar tomma strängar. Den senare tilldelar emellertid en initial buffert, vilket gör att den initialt blir långsammare, men hjälper till att minska efterföljande tilldelningar. Om den slutliga storleken på strängen är känd, bör String::with_capacity föredras.

Strängskivning

fn main() {
    let english = "Hello, World!";

    println!("{}", &english[0..5]); // Prints "Hello"
    println!("{}", &english[7..]);  // Prints "World!"
}

Observera att vi måste använda & operatören här. Den tar en referens och ger därmed kompilatorn information om storleken på skivstypen, som den behöver för att skriva ut den. Utan referensen println! de två ut println! samtal skulle vara ett kompileringstidsfel.

Varning: Skivning fungerar efter byteförskjutning , inte teckenförskjutning och kommer att få panik när gränser inte är på en teckengräns:

fn main() {
    let icelandic = "Halló, heimur!"; // note that “ó” is two-byte long in UTF-8

    println!("{}", &icelandic[0..6]); // Prints "Halló", “ó” lies on two bytes 5 and 6
    println!("{}", &icelandic[8..]);  // Prints "heimur!", the “h” is the 8th byte, but the 7th char
    println!("{}", &icelandic[0..5]); // Panics!
}

Detta är också anledningen till att strängar inte stöder enkel indexering (t.ex. icelandic[5] ).

Dela upp en sträng

let strings = "bananas,apples,pear".split(",");

split returnerar en iterator.

for s in strings {
  println!("{}", s)
}

Och kan "samlas in" i en Vec med Iterator::collect metoden.

let strings: Vec<&str> = "bananas,apples,pear".split(",").collect(); // ["bananas", "apples", "pear"]

Från lånad till ägd

// all variables `s` have the type `String`
let s = "hi".to_string();  // Generic way to convert into `String`. This works
                           // for all types that implement `Display`.

let s = "hi".to_owned();   // Clearly states the intend of obtaining an owned object

let s: String = "hi".into();       // Generic conversion, type annotation required
let s: String = From::from("hi");  // in both cases!

let s = String::from("hi");  // Calling the `from` impl explicitly -- the `From` 
                             // trait has to be in scope!

let s = format!("hi");       // Using the formatting functionality (this has some
                             // overhead)

Bortsett från format!() Är alla metoderna ovan lika snabba.

Bryta långa strängbokstäver

Bryt vanliga strängbokstäver med \ tecknet

let a = "foobar";
let b = "foo\
         bar";

// `a` and `b` are equal.
assert_eq!(a,b);

Bryt råsträngslitteraler för att separera strängar och gå med dem med concat! makro

let c = r"foo\bar";
let d = concat!(r"foo\", r"bar");

// `c` and `d` are equal.
assert_eq!(c, d);


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow