Other Aggregate Types

  • Arrays with size e.g. [int;12]

  • Vec

  • Strings

Arrays

  • Array types include their size

    [char; 7]
    
  • There are no "const generics": every size is different

  • Arrays are copy if their elements are

  • Initialization syntax is either by copyable value

    let a = [0u16; 12];
    

    or by list

    let a = ['a', 'b', 'c'];
    
  • Arrays must always be created initialized.

  • The intent of arrays is that small ones are useful in numeric computing e.g. [f32;4] and large ones are usually via slices

Slices

  • Slice types are types like [char] that denote a sequence of values of unspecified size: the user can't create these directly

  • Taking the address of an array normally produces a a slice reference

    let a: &[char] = &['a', 'b'];
    
  • A slice reference is a "fat pointer" that carries both the slice address and slice length.

  • Both arrays and slices have a .len() method: slices have to have it.

Vec

  • A Vec is an owned value that lives on the heap. The size is part of the Vec, and the Vec can be grown and shrunk, often with the .push() and .pop() methods

    • vec.push(val) pushes val on the end of vec, increasing its length. The usual ownership rules apply: .push() borrows vec mutably, and val moves into vec

    • vec.pop() moves the value on the end of vec out as the result, decreasing vec's length. .pop() returns Option<T>: it returns None if the vec is empty and Some(val) otherwise

  • A Vec is not Copy, but it is Clone if its elements are Clone

  • A new empty Vec can be created via

    Vec::new()
    Vec::with_capacity(15)
    

    Note that that second thing is also empty — it just has reserved space for efficiency

  • The vec! macro can be used to create vectors:

    vec![1, 2, 3]
    
  • A Vec reference is normally auto-converted to a slice

    let s: &[char] = &vec![1, 2, 3];
    

String

  • A String is an owned UTF-8 text on the heap. To say that it is a sequence of chars is wrong: the text is compressed according to the UTF-8 standard

  • A String is not Copy but it is Clone

  • An empty String can be created with

    String::new()
    String::with_capacity(12)
    

    The capacity is in bytes, not chars

    .push() and .pop() can be used to add or remove characters on the end of a String

    Strings are often created using the .to_string() method of various other datatypes

    The format! macro can be used to create strings println!-style. There is no formatln! for some reason

    format!("{} bottles of root beer", 99)
    
  • String indexing is in bytes because UTF-8, if it were supported, which it isn't. Use the .chars() method to iterate over the characters of a String

    // This will not compile.
    for i in 0..s.len() {
        println!("{}", s[i]);
    }
    
    // Write this instead.
    for c in s.chars() {
        println!("{}", c);
    }
    

str

  • str is a slice of UTF-8 text of unspecified length. There is no obvious way to create a value of this type directly in a Rust program. Instead, this type is used as a slice &str

  • A string constant is a string slice

    let s: &str = "hello world";
    

    A String reference normally autorefs to a string slice

    let s: &str = &5.to_string();
    
  • There's a whole pile of methods for manipulating &str: see the docs

Last modified: Wednesday, 15 January 2020, 4:15 PM