Wycińki łańcuchowe

  1. Wycinek łańcuchowy (ang. string slice) umożliwia odwołanie się do fragmentu tekstu, nie powodując pożyczenia wartości.

    let s = String::from("string slice demonstration");
     
    let s1 = &s[7..12];
     
    println!("{}", s1);
  2. Możliwe jest również odwołanie podając tylko górne lub dolne ograniczenie

    let s = String::from("string slice demonstration");
     
    let s1 = &s[..12];
    let s2 = &s[6..];
    let s3 = &s[..];
  3. Typ wycinka łancuchowego to &str

Wypożyczenie za pomocą wycinka

  1. Wycinki należy traktować jako niemutowalne wypożyczenie danej wartości. Przyjrzyj się poniższemu fragmentowi kodu, który definiuje funkcję zwracającą wycinek będący pierwszym słowem w podanym tekście.
    fn main() {
        let s = String::from("text that illustrates slices");
        let first = first_word(&s[..]);
        
        // s.clear(); //tries to modify text
     
        println!("{first}");
    }   
     
    fn first_word(s : &str) -> &str {
        let bytes = s.as_bytes();
     
        for (i, &item) in bytes.iter().enumerate() {
            if item == b' ' {
                return &s[..i]
            }
        }
        s
    }
  2. Odkomentuj funkcję czyszczącą zawartość zmiennej s (linia 5). Przeanalizuj błąd kompilatora. Popraw deklarację zmiennej s na mutowalną i uruchom jeszcze raz kompilację.
  3. Literały tekstowe (ie. tekst definiowany w kodzie) jest typu &str. Uprość powyższy kod, aby nie trzeba było definiować łańcucha znaków (zmienna typu String).
    let s : &str = "text that illustrates slices";
    let first = first_word(s);

Ćwiczenie - napisz funkcje przetwarzające tekst

Zaimplementuj funkcje trim_me, compose_me, replace_me nie zmieniając ich sygnatur tak, aby wszystkie asercje zakończyły się powodzeniem.

fn trim_me(input: &str) -> String {
    // TODO: Remove whitespace from both ends of a string!
    
}
 
fn compose_me(input: &str) -> String {
    // TODO: Add " world!" to the string! There's multiple ways to do this!
 
}
 
fn replace_me(input: &str) -> String {
    // TODO: Replace "cars" in the string with "balloons"!
}
 
fn main() {
    assert_eq!(trim_me("Hello!     "), "Hello!");
    assert_eq!(trim_me("  What's up!"), "What's up!");
    assert_eq!(trim_me("   Hola!  "), "Hola!");
 
 
    assert_eq!(compose_me("Hello"), "Hello world!");
    assert_eq!(compose_me("Goodbye"), "Goodbye world!");
 
 
    assert_eq!(replace_me("I think cars are cool"), "I think balloons are cool");
    assert_eq!(replace_me("I love to look at cars"), "I love to look at balloons");
}

Źródło: rustlings

Wycinki tablicowe

  1. W analogiczny sposób możemy zdefiniować wycinki dla typów tablicowych
    fn main() {
        let array = [1, 2, 3, 4, 5];
        let array_slice : &[i32] = &array[2..4];
        println!("{:?}", array_slice);
    }