Index

Rust

  1. Guessing Game
  2. Common Programming Concepts
    1. Variables and Mutability
    2. Data Types
    3. Function
    4. Control Flow
  3. Understanding Ownership
    1. References and Borrowing
    2. The Slice Type
  4. Using Structs
    1. An Example Program Using Structs
    2. Method Syntax
  5. Enums and Pattern Matching
    1. The match Control Flow Operator
    2. Concise Control Flow with if let
  6. Managing Growing Projects with Packages, Crates, and Modules
    1. Defining Modules to Control Scope and Privacy
    2. Paths for Referring to an Item in the Module Tree
    3. Bringing Paths into Scope with the use Keyword
    4. Separating Modules into Different Files
  7. Common Collections
    1. Storing UTF-8 Encoded Text with Strings
    2. Storing Keys with Associated Values in Hash Maps
  8. Error Handling
    1. Unrecoverable Errors with panic!
    2. Recoverable Errors with Result
  9. Generic Types, Traits, and Lifetimes
    1. Traits: Defining Shared Behavior
    2. Generics Rust by Example
      1. Functions
      2. Implementation
  10. Writing Automated Tests
  11. Object Oriented Programming
  12. Adding dependancies
  13. Option Take
  14. RefCell
  15. mem
  16. Data Structure
    1. Linked List
    2. Binary search tree
    3. N-ary Sum tree
  17. Recipe
    1. Semi colon
    2. Calling rust from python
    3. Default
    4. Crytocurrency With rust
    5. Function chaining
    6. Question Mark Operator
    7. Tests with println
    8. lib and bin
    9. Append vector to hash map
    10. Random Number
    11. uuid4
    12. uwrap and option
  18. Blockchain with Rust
  19. Near Protocol
    1. Startup code
    2. Couter
    3. Status
    4. Avrit
  20. Actix-web

Storing UTF-8 Encoded Text with Strings

Storing UTF-8 Encoded Text with Strings

What Is a String?
We’ll first define what we mean by the term string. Rust has only one string type in the core language, which is the string slice str that is usually seen in its borrowed form &str.

Creating a New String
fn main() {
    let mut s = String::new();
}



Often, we’ll have some initial data that we want to start the string with. For that, we use the to_string method, which is available on any type that implements the Display trait, as string literals do
    let data = "initial contents";

    let s = data.to_string();

    // the method also works on a literal directly:
    let s = "initial contents".to_string();


str, only used as &str, is a string slice, a reference to a UTF-8 byte array.
String is what used to be ~str, a growable, owned UTF-8 byte array.
// owned String, heap allocated
let x = String::from("Hi");

//  reference to string literal hardcoded in binary, 'static &str
let x = "Hi";


String is the dynamic heap string type, like Vec: use it when you need to own or modify your string data.

str is an immutable sequence of UTF-8 bytes of dynamic length somewhere in memory. Since the size is unknown, one can only handle it behind a pointer. This means that str most commonly appears as &str: a reference to some UTF-8 data, normally called a "string slice" or just a "slice". A slice is just a view onto some data, and that data can be anywhere.

Remember that strings are UTF-8 encoded, so we can include any properly encoded data in them
fn main() {
    let hello = String::from("السلام عليكم");
    let hello = String::from("Dobrý den");
    let hello = String::from("Hello");
    let hello = String::from("שָׁלוֹם");
    let hello = String::from("नमस्ते");
    let hello = String::from("こんにちは");
    let hello = String::from("안녕하세요");
    let hello = String::from("你好");
    let hello = String::from("Olá");
    let hello = String::from("Здравствуйте");
    let hello = String::from("Hola");
}

All of these are valid String values.

Updating a String


A String can grow in size and its contents can change, just like the contents of a Vec<T>, if you push more data into it. In addition, you can conveniently use the + operator or the format! macro to concatenate String values.

Appending to a String with push_str and push
We can grow a String by using the push_str method to append a string slice,
    let mut s = String::from("foo");
    s.push_str("bar");


The push_str method takes a string slice because we don’t necessarily want to take ownership of the parameter.
fn main() {
    let mut s1 = String::from("foo");
    let s2 = "bar";
    s1.push_str(s2);
    println!("s2 is {}", s2);
}


If the push_str method took ownership of s2, we wouldn’t be able to print its value on the last line. However, this code works as we’d expect!

images/886-1.png

The push method takes a single character as a parameter and adds it to the String.
fn main() {
    let mut s = String::from("lo");
    s.push('l');
}


Concatenation with the + Operator or the format! Macro
fn main() {
    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");
    let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used
}


Read the details about deref coercion

If we need to concatenate multiple strings, the behavior of the + operator gets unwieldy:
    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");

    let s = s1 + "-" + &s2 + "-" + &s3;


For more complicated string combining, we can use the format! macro
fn main() {
    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");

    let s = format!("{}-{}-{}", s1, s2, s3);
}


This code also sets s to tic-tac-toe. The format! macro works in the same way as println!, but instead of printing the output to the screen, it returns a String with the contents. The version of the code using format! is much easier to read and doesn’t take ownership of any of its parameters.
fn main() {
    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");

    let s = format!("{}-{}-{}", s1, s2, s3);
    println!("{}",s);
    println!("{}", s1); // It prints, s1 is not moved
}


images/886-2.png

Indexing into Strings

Error code:
    let s1 = String::from("hello");
    let h = s1[0];

Rust strings don’t support indexing. But why not? To answer that question, we need to discuss how Rust stores strings in memory.

For details link

Methods for Iterating Over Strings
for c in "नमस्ते".chars() {
    println!("{}", c);
}


This code will print the following:








The bytes method returns each raw byte, which might be appropriate for your domain:
for b in "नमस्ते".bytes() {
    println!("{}", b);
}


This code will print the 18 bytes that make up this String:
224
164
// --snip--
165
135