2377 lines
60 KiB
Text
2377 lines
60 KiB
Text
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Arrays, Vectors & Slices"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Arrays\n",
|
||
"\n",
|
||
"* The type `[T; N]` represents an array of `N` values, each of type `T`.\n",
|
||
"* An array’s size is a constant determined at compile time, and is part of the type; \n",
|
||
" * you can’t append new elements, \n",
|
||
" * or shrink an array."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Creating arrays"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[0, 1, 4, 9, 16, 25]"
|
||
]
|
||
},
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let data: [i32; 6] = [0, 1, 4, 9, 16, 25];\n",
|
||
"data"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[\"zero\", \"one\", \"two\", \"three\", \"four\", \"five\"]"
|
||
]
|
||
},
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let words: [&str; 6] = [\"zero\", \"one\", \"two\", \"three\", \"four\", \"five\"];\n",
|
||
"words"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[[1, 2, 3], [4, 5, 6], [7, 8, 9]]"
|
||
]
|
||
},
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut matrix: [[i32; 3]; 3] = [\n",
|
||
" [1, 2, 3],\n",
|
||
" [4, 5, 6],\n",
|
||
" [7, 8, 9],\n",
|
||
"];\n",
|
||
"matrix"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Assignment of `[V; N]` fills an array of size `N` with a value `V`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
|
||
]
|
||
},
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut buffer = [0u8; 32]; // 32-byte buffer, filled with zero bytes\n",
|
||
"buffer"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Accessing Array Elements\n",
|
||
"\n",
|
||
"* Accessing an element of an array can be done using the index operator `[]`\n",
|
||
"* Indexing is 0-based\n",
|
||
"* Accessing an element outside the bounds of an array will cause a panic"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 16,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"\"two\""
|
||
]
|
||
},
|
||
"execution_count": 16,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let numbers = [\"zero\", \"one\", \"two\", \"three\", \"four\", \"five\"];\n",
|
||
"numbers[2]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Safe indexing can be done using the `get` method of the slice\n",
|
||
"* The `get` method returns an `Option` type, which is `Some` if the index is in bounds, and `None` if it is out of bounds"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 18,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"\"two\"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"match numbers.get(2) {\n",
|
||
" Some(&x) => println!(\"{:?}\", x),\n",
|
||
" None => println!(\"No such element\"),\n",
|
||
"};"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Modifying Array Elements"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[1, 42, 3, 4, 665]"
|
||
]
|
||
},
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut numbers = [1, 2, 3, 4, 5];\n",
|
||
"\n",
|
||
"numbers[1] = 42;\n",
|
||
"\n",
|
||
"if let Some(x) = numbers.get_mut(4) {\n",
|
||
" *x = 665;\n",
|
||
"}\n",
|
||
"\n",
|
||
"numbers"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Iterating Through Arrays\n",
|
||
"\n",
|
||
"* `for` loop"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Monday\n",
|
||
"Tuesday\n",
|
||
"Wednesday\n",
|
||
"Thursday\n",
|
||
"Friday\n",
|
||
"Saturday\n",
|
||
"Sunday\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"()"
|
||
]
|
||
},
|
||
"execution_count": 24,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let days = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"];\n",
|
||
"\n",
|
||
"// using a for-in loop\n",
|
||
"for day in days {\n",
|
||
" println!(\"{day}\");\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* is using the `iter()` method that creates an iterator over the elements of the array"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 25,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Monday\n",
|
||
"Tuesday\n",
|
||
"Wednesday\n",
|
||
"Thursday\n",
|
||
"Friday\n",
|
||
"Saturday\n",
|
||
"Sunday\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"()"
|
||
]
|
||
},
|
||
"execution_count": 25,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"// using a for loop with an iterator\n",
|
||
"for day in days.iter() {\n",
|
||
" println!(\"{}\", day);\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* it is also possible to iterate over elements of an array using indexes"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 26,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0 - Monday\n",
|
||
"1 - Tuesday\n",
|
||
"2 - Wednesday\n",
|
||
"3 - Thursday\n",
|
||
"4 - Friday\n",
|
||
"5 - Saturday\n",
|
||
"6 - Sunday\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"()"
|
||
]
|
||
},
|
||
"execution_count": 26,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"// using a for loop with index\n",
|
||
"for index in 0..days.len() {\n",
|
||
" println!(\"{} - {}\", index, days[index])\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* `iter_mut()` method that creates an iterator over mutable references to the elements of the array"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 32,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[2, 4, 6, 8, 10]"
|
||
]
|
||
},
|
||
"execution_count": 32,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut numbers = [1, 2, 3, 4, 5];\n",
|
||
"\n",
|
||
"for number in &mut numbers {\n",
|
||
" *number *= 2;\n",
|
||
"}\n",
|
||
"\n",
|
||
"numbers"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 33,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[5, 7, 9, 11, 13]"
|
||
]
|
||
},
|
||
"execution_count": 33,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"for number in numbers.iter_mut() {\n",
|
||
" *number += 3;\n",
|
||
"}\n",
|
||
"\n",
|
||
"numbers"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Array Length"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 34,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"7"
|
||
]
|
||
},
|
||
"execution_count": 34,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let array_size = days.len();\n",
|
||
"array_size"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Copying Arrays\n",
|
||
"\n",
|
||
"* Arrays are copied by value (if the element type is `Copy`)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 37,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"[1, 2, 3, 4]\n",
|
||
"[42, 2, 3, 4]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut original: [i32; 4] = [1, 2, 3, 4];\n",
|
||
"let mut copied: [i32; 4] = original;\n",
|
||
"\n",
|
||
"copied[0] = 42;\n",
|
||
"assert_eq!(&copied, &[42, 2, 3, 4]); \n",
|
||
"\n",
|
||
"println!(\"{:?}\", original);\n",
|
||
"println!(\"{:?}\", copied);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* When elements are not `Copy`, the array is moved"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 40,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let mut words: [String; 4] = [\"zero\".to_string(), \"one\".to_string(), \"two\".to_string(), \"three\".to_string()];\n",
|
||
"let target = words; // move words into target"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* To copy an array, you can use the `clone()` method"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 42,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"[\"zero!!!\", \"one\", \"two\", \"three\"]\n",
|
||
"[\"zero\", \"one\", \"two\", \"three\"]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut words: [String; 4] = [\"zero\".to_string(), \"one\".to_string(), \"two\".to_string(), \"three\".to_string()];\n",
|
||
"let backup_words = words.clone();\n",
|
||
"\n",
|
||
"words[0].push_str(\"!!!\");\n",
|
||
"assert_eq!(words[0], \"zero!!!\");\n",
|
||
"\n",
|
||
"println!(\"{:?}\", words);\n",
|
||
"println!(\"{:?}\", backup_words);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### to_owned()\n",
|
||
"\n",
|
||
"* The `to_owned()` method can be applied to borrowed array to create a copy of the array"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 43,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"original_array = [\"one\", \"two\", \"three\", \"four\"] - [&str; 4]\n",
|
||
"borrowed_array = [\"one\", \"two\", \"three\", \"four\"] - &[&str; 4]\n",
|
||
"owned_vector = [\"one\", \"two\", \"three\", \"four\"] - [&str; 4]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"use std::any::{TypeId, type_name};\n",
|
||
"\n",
|
||
"fn get_type<T>(_: &T) -> String {\n",
|
||
" format!(\"{}\", type_name::<T>())\n",
|
||
"}\n",
|
||
"\n",
|
||
"fn main() {\n",
|
||
" let original_array: [&str; 4] = [\"one\", \"two\", \"three\", \"four\"];\n",
|
||
" let borrowed_array: &[&str; 4] = &original_array;\n",
|
||
" let owned_vector = borrowed_array.to_owned();\n",
|
||
"\n",
|
||
" println!(\"original_array = {original_array:?} - {}\", get_type(&original_array));\n",
|
||
" println!(\"borrowed_array = {original_array:?} - {}\", get_type(&borrowed_array));\n",
|
||
" println!(\"owned_vector = {owned_vector:?} - {}\", get_type(&owned_vector));\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Arrays - Example"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 46,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[false, false, true, true, false, true, false, true, false, false, false, true, false, true, false, false, false, true, false, true, false, false, false, true, false, false, false, false, false, true, false, true, false, false, false, false, false, true, false, false, false, true, false, true, false, false, false, true, false, false, false, false, false, true, false, false, false, false, false, true, false, true, false, false, false, false, false, true, false, false, false, true, false, true, false, false, false, false, false, true, false, false, false, true, false, false, false, false, false, true, false, false, false, false, false, false, false, true, false, false]"
|
||
]
|
||
},
|
||
"execution_count": 46,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"fn is_prime(n: usize) -> bool {\n",
|
||
" if n < 2 {\n",
|
||
" return false;\n",
|
||
" }\n",
|
||
" for i in 2..=((n as f64).sqrt() as usize) {\n",
|
||
" if n % i == 0 {\n",
|
||
" return false;\n",
|
||
" }\n",
|
||
" }\n",
|
||
" true\n",
|
||
"}\n",
|
||
"\n",
|
||
"const N: usize = 100;\n",
|
||
"\n",
|
||
"let mut primes_sieve = [true; N];\n",
|
||
"primes_sieve[0] = false;\n",
|
||
"primes_sieve[1] = false;\n",
|
||
"\n",
|
||
"for i in 2..10 {\n",
|
||
" if primes_sieve[i] {\n",
|
||
" let mut j = i * i;\n",
|
||
" while j < N {\n",
|
||
" primes_sieve[j] = false;\n",
|
||
" j += i;\n",
|
||
" }\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"primes_sieve"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 47,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]"
|
||
]
|
||
},
|
||
"execution_count": 47,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"primes_sieve.iter().enumerate()\n",
|
||
" .filter_map(|(index, &is_prime)| if is_prime { Some(index) } else { None })\n",
|
||
" .collect::<Vec<usize>>()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Multi-dimensionals Arrays"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 48,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"_ X O \n",
|
||
"O X _ \n",
|
||
"X _ O \n",
|
||
"\n",
|
||
"Updated Tic-Tac-Toe Board:\n",
|
||
"_ X O \n",
|
||
"O X X \n",
|
||
"X O O \n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"fn main() {\n",
|
||
" let mut tic_tac_toe: [[char; 3]; 3] = [\n",
|
||
" ['_', 'X', 'O'],\n",
|
||
" ['O', 'X', '_'],\n",
|
||
" ['X', '_', 'O']\n",
|
||
" ];\n",
|
||
"\n",
|
||
" print_tic_tac_toe(&tic_tac_toe);\n",
|
||
"\n",
|
||
" tic_tac_toe[1][2] = 'X';\n",
|
||
" tic_tac_toe[2][1] = 'O';\n",
|
||
"\n",
|
||
" println!(\"\\nUpdated Tic-Tac-Toe Board:\");\n",
|
||
" print_tic_tac_toe(&tic_tac_toe);\n",
|
||
"}\n",
|
||
"\n",
|
||
"fn print_tic_tac_toe(board: &[[char; 3]; 3]) {\n",
|
||
" for row in board {\n",
|
||
" for cell in row {\n",
|
||
" print!(\"{cell} \");\n",
|
||
" }\n",
|
||
" println!();\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Vectors"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* A vector `Vec<T>` is a resizable array of elements of type `T`, allocated on the heap."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Creating Vectors"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* `Vec::new()` - creates empty vector"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 52,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[]"
|
||
]
|
||
},
|
||
"execution_count": 52,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut v = Vec::<i32>::new();\n",
|
||
"assert_eq!(v.len(), 0);\n",
|
||
"\n",
|
||
"v"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* vector is resized automatically when elements are added"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 53,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[2, 3, 7, 11]"
|
||
]
|
||
},
|
||
"execution_count": 53,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"v.push(2);\n",
|
||
"v.push(3);\n",
|
||
"v.push(7);\n",
|
||
"v.push(11);\n",
|
||
"\n",
|
||
"assert_eq!(v.len(), 4);\n",
|
||
"\n",
|
||
"v"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* `vec!` macro allows to create a vector initialized with given items"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 54,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[2, 3, 7, 11]"
|
||
]
|
||
},
|
||
"execution_count": 54,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut v = vec![2, 3, 7, 11];\n",
|
||
"\n",
|
||
"v"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* `vec![V; N]` - creates a vector with size `N` filled with `V`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 55,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
|
||
]
|
||
},
|
||
"execution_count": 55,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"fn create_pixel_buffer(rows: usize, cols: usize) -> Vec<u8> {\n",
|
||
" vec![0u8; rows * cols]\n",
|
||
"}\n",
|
||
"\n",
|
||
"create_pixel_buffer(4, 3)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Another possibility is to build a vector from the values produced by an iterator:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 57,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
|
||
]
|
||
},
|
||
"execution_count": 57,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let numbers: Vec<i32> = (1..=10).collect();\n",
|
||
"\n",
|
||
"numbers"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Accessing and Modifying Elements"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 63,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let mut words: Vec<String> = [\"one\".to_string(), \"two\".to_string(), \"three\".to_string()].to_vec();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Indexing"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 64,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"\"one\""
|
||
]
|
||
},
|
||
"execution_count": 64,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"words[0]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 65,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[\"one\", \"two and a half\", \"three\"]"
|
||
]
|
||
},
|
||
"execution_count": 65,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"words[1].push_str(\" and a half\");\n",
|
||
"words"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* moving elements out of a vector when indexing is not allowed by default\n",
|
||
"* to move elements, use `drain` or `into_iter`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 70,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "Error",
|
||
"evalue": "cannot move out of index of `Vec<String>`",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m[E0507] Error:\u001b[0m cannot move out of index of `Vec<String>`",
|
||
" \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0m command_70:1:1 \u001b[38;5;246m]\u001b[0m",
|
||
" \u001b[38;5;246m│\u001b[0m",
|
||
" \u001b[38;5;246m1 │\u001b[0m \u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mf\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mw\u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54md\u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54m[\u001b[0m\u001b[38;5;54m0\u001b[0m\u001b[38;5;54m]\u001b[0m\u001b[38;5;249m;\u001b[0m",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;100m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;68m│\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m help: consider borrowing here: `&`",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m│\u001b[0m \u001b[38;5;68m│\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m move occurs because value has type `String`, which does not implement the `Copy` trait",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;68m│\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m help: consider cloning the value if the performance cost is acceptable: `.clone()`",
|
||
"\u001b[38;5;246m───╯\u001b[0m"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"let first = words[0];\n",
|
||
"first"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 71,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[\"one\", \"two and three quarters\", \"three\"]"
|
||
]
|
||
},
|
||
"execution_count": 71,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"{\n",
|
||
" let second: &String = &words[1];\n",
|
||
" let second_mutable: &mut String = &mut words[1];\n",
|
||
" *second_mutable = \"two and three quarters\".to_string();\n",
|
||
"}\n",
|
||
"\n",
|
||
"words"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Safe Access\n",
|
||
"* indexing with `[]` operator - panics if index is out of bounds\n",
|
||
"* `get()` method - safe access returning `Option<&T>`\n",
|
||
"* `get_mut()` method - safe mutable access returning `Option<&mut T>`\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 75,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stderr",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"\n",
|
||
"thread '<unnamed>' panicked at src\\lib.rs:188:6:\n",
|
||
"index out of bounds: the len is 3 but the index is 3\n",
|
||
"stack backtrace:\n",
|
||
" 0: std::panicking::begin_panic_handler\n",
|
||
" at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library\\std\\src\\panicking.rs:697\n",
|
||
" 1: core::panicking::panic_fmt\n",
|
||
" at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library\\core\\src\\panicking.rs:75\n",
|
||
" 2: core::panicking::panic_bounds_check\n",
|
||
" at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library\\core\\src\\panicking.rs:280\n",
|
||
" 3: <unknown>\n",
|
||
" 4: <unknown>\n",
|
||
" 5: <unknown>\n",
|
||
" 6: <unknown>\n",
|
||
" 7: <unknown>\n",
|
||
" 8: <unknown>\n",
|
||
" 9: <unknown>\n",
|
||
" 10: <unknown>\n",
|
||
" 11: <unknown>\n",
|
||
" 12: <unknown>\n",
|
||
" 13: BaseThreadInitThunk\n",
|
||
" 14: RtlUserThreadStart\n",
|
||
"note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"words[3]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 74,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"No third word\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"()"
|
||
]
|
||
},
|
||
"execution_count": 74,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"{\n",
|
||
" let third: Option<&String> = words.get(3);\n",
|
||
"\n",
|
||
" match third {\n",
|
||
" Some(word) => println!(\"{}\", word),\n",
|
||
" None => println!(\"No third word\")\n",
|
||
" }\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Length & Capacity\n",
|
||
"\n",
|
||
"* A `Vec<T>` consists of three values: \n",
|
||
" * a pointer to the heap-allocated buffer allocated to hold the elements; \n",
|
||
" * the number of elements that buffer has the capacity to store; \n",
|
||
" * and the number it actually contains now (in other words, its length). \n",
|
||
"* When the buffer has reached its capacity, adding another element to the vector entails allocating a larger buffer, copying the present contents into it, updating the vector’s pointer and capacity to describe the new buffer, and finally freeing the old one."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 76,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let mut v = Vec::with_capacity(2);\n",
|
||
"assert_eq!(v.len(), 0);\n",
|
||
"assert_eq!(v.capacity(), 2);\n",
|
||
"\n",
|
||
"v.push(1);\n",
|
||
"v.push(2);\n",
|
||
"assert_eq!(v.len(), 2);\n",
|
||
"assert_eq!(v.capacity(), 2);\n",
|
||
"\n",
|
||
"v.push(3);\n",
|
||
"assert_eq!(v.len(), 3);\n",
|
||
"assert_eq!(v.capacity(), 4);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Removing elements"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* `pop()` method removes the last element and returns it as `Option<T>`:\n",
|
||
" * `None` if the vector was already empty, \n",
|
||
" * or `Some(v)` if its last element had been `v`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 77,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let mut guitars = vec![\"fender\", \"gibson\"];\n",
|
||
"assert_eq!(guitars.pop(), Some(\"gibson\"));\n",
|
||
"assert_eq!(guitars.pop(), Some(\"fender\"));\n",
|
||
"assert_eq!(guitars.pop(), None);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* `remove(index)` - removes item with a given index"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 78,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[\"fender\", \"yamaha\"]"
|
||
]
|
||
},
|
||
"execution_count": 78,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut guitars = vec![\"fender\", \"gibson\", \"yamaha\"];\n",
|
||
"guitars.remove(1);\n",
|
||
"guitars"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Iterating over Vectors"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Using `for` loop"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 79,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"1 2 3 4 5 \n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"let numbers = vec![1, 2, 3, 4, 5];\n",
|
||
"\n",
|
||
"for number in numbers {\n",
|
||
" print!(\"{} \", number);\n",
|
||
"}\n",
|
||
"\n",
|
||
"println!();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 80,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "Error",
|
||
"evalue": "borrow of moved value: `words`",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m[E0382] Error:\u001b[0m borrow of moved value: `words`",
|
||
" \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0m command_80:1:1 \u001b[38;5;246m]\u001b[0m",
|
||
" \u001b[38;5;246m│\u001b[0m",
|
||
" \u001b[38;5;246m1 │\u001b[0m \u001b[38;5;249ml\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;100mw\u001b[0m\u001b[38;5;100mo\u001b[0m\u001b[38;5;100mr\u001b[0m\u001b[38;5;100md\u001b[0m\u001b[38;5;100ms\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mv\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mc\u001b[0m\u001b[38;5;249m!\u001b[0m\u001b[38;5;249m[\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m,\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mh\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249m\"\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249m_\u001b[0m\u001b[38;5;249ms\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249mg\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m]\u001b[0m\u001b[38;5;249m;\u001b[0m",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m┬\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;100m╰\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m\u001b[38;5;100m─\u001b[0m move occurs because `words` has type `Vec<String>`, which does not implement the `Copy` trait",
|
||
" \u001b[38;5;240m │\u001b[0m ",
|
||
" \u001b[38;5;246m3 │\u001b[0m \u001b[38;5;249mf\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mw\u001b[0m\u001b[38;5;249mo\u001b[0m\u001b[38;5;249mr\u001b[0m\u001b[38;5;249md\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249mi\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;54mw\u001b[0m\u001b[38;5;54mo\u001b[0m\u001b[38;5;54mr\u001b[0m\u001b[38;5;54md\u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m{\u001b[0m",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;68m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;68m╰\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m\u001b[38;5;68m─\u001b[0m help: consider iterating over a slice of the `Vec<String>`'s content to avoid moving into the `for` loop: `&`",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m│\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m `words` moved due to this implicit call to `.into_iter()`",
|
||
" \u001b[38;5;240m │\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;115mNote\u001b[0m: note: `into_iter` takes ownership of the receiver `self`, which moves `words`",
|
||
"\u001b[38;5;246m───╯\u001b[0m"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"let words = vec![\"one\".to_string(), \"two\".to_string(), \"three\".to_string()];\n",
|
||
"\n",
|
||
"for word in words {\n",
|
||
" println!(\"{}\", word);\n",
|
||
"}\n",
|
||
"\n",
|
||
"words"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 81,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"one\n",
|
||
"two\n",
|
||
"three\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[\"one\", \"two\", \"three\"]"
|
||
]
|
||
},
|
||
"execution_count": 81,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let words = vec![\"one\".to_string(), \"two\".to_string(), \"three\".to_string()];\n",
|
||
"\n",
|
||
"for word in words.iter() {\n",
|
||
" println!(\"{}\", word);\n",
|
||
"}\n",
|
||
"\n",
|
||
"words"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Using `iter_mut()` for Mutable Iteration"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* `iter_mut()` creates an iterator over mutable references to the elements of the vector"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 83,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[11, 12, 13, 14, 15]"
|
||
]
|
||
},
|
||
"execution_count": 83,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut numbers = vec![1, 2, 3, 4, 5];\n",
|
||
"\n",
|
||
"for n in numbers.iter_mut() {\n",
|
||
" *n += 10;\n",
|
||
"}\n",
|
||
"\n",
|
||
"numbers"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* the same can be achieved using iteration over mutable slice - `&mut collection`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 84,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"[33, 36, 39, 42, 45]"
|
||
]
|
||
},
|
||
"execution_count": 84,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"for n in &mut numbers {\n",
|
||
" *n *= 3;\n",
|
||
"}\n",
|
||
"\n",
|
||
"numbers"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Using `enumerate` for Index & Value"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 38,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Index: 0 - fender\n",
|
||
"Index: 1 - gibson\n",
|
||
"Index: 2 - yamaha\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"()"
|
||
]
|
||
},
|
||
"execution_count": 38,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut guitars = vec![\"fender\", \"gibson\", \"yamaha\"];\n",
|
||
"\n",
|
||
"for (index, guitar) in guitars.iter().enumerate() {\n",
|
||
" println!(\"Index: {} - {}\", index, guitar);\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Slices"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* A **slice**, written `[T]` without specifying the length, is a region of an array or vector. \n",
|
||
"* Since a slice can be any length, slices can’t be stored directly in variables or passed as function arguments. **Slices are always passed by reference**.\n",
|
||
"* A reference to a slice is a **fat pointer**: a two-word value comprising a pointer to the slice’s first element, and the number of elements in the slice.\n",
|
||
"* A reference to a slice is a non-owning pointer to several values"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 85,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"sv: 0 0.707 1 0.707 \n",
|
||
"sa: 0 -0.707 -1 -0.707 \n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"fn main() {\n",
|
||
" let v: Vec<f64> = vec![0.0, 0.707, 1.0, 0.707];\n",
|
||
" let a: [f64; 4] = [0.0, -0.707, -1.0, -0.707];\n",
|
||
"\n",
|
||
" let sv: &[f64] = &v;\n",
|
||
" let sa: &[f64] = &a;\n",
|
||
"\n",
|
||
" fn print(data: &[f64], desc: &str) {\n",
|
||
" print!(\"{desc}: \");\n",
|
||
" for item in data {\n",
|
||
" print!(\"{} \", item);\n",
|
||
" }\n",
|
||
" println!();\n",
|
||
" }\n",
|
||
"\n",
|
||
" print(sv, \"sv\");\n",
|
||
" print(sa, \"sa\");\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"vscode": {
|
||
"languageId": "rust"
|
||
}
|
||
},
|
||
"source": [
|
||
"### Creating slices"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 93,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"slice_all: [ 1 2 3 4 5 6 7 8 9 10 ]\n",
|
||
"slice_first_five: [ 1 2 3 4 5 ]\n",
|
||
"slice_last_five: [ 6 7 8 9 10 ]\n",
|
||
"data: [ 1 2 3 4 0 0 0 8 9 10 ]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"// Function to print elements of a slice with a description\n",
|
||
"fn print(data: &[i32], desc: &str) {\n",
|
||
" print!(\"{desc}: [ \");\n",
|
||
" for item in data {\n",
|
||
" print!(\"{} \", item);\n",
|
||
" }\n",
|
||
" println!(\"]\");\n",
|
||
"}\n",
|
||
"\n",
|
||
"// Function to set all elements of a mutable slice to zero\n",
|
||
"fn zero(data: &mut [i32]) {\n",
|
||
" for item in data {\n",
|
||
" *item = 0;\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"fn main() {\n",
|
||
" let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n",
|
||
"\n",
|
||
" let slice_all: &[i32] = &data[..];\n",
|
||
" print(slice_all, \"slice_all\");\n",
|
||
"\n",
|
||
" let slice_first_five: &[i32] = &data[0..5];\n",
|
||
" print(slice_first_five, \"slice_first_five\");\n",
|
||
"\n",
|
||
" let slice_last_five: &[i32] = &data[5..];\n",
|
||
" print(slice_last_five, \"slice_last_five\");\n",
|
||
"\n",
|
||
" let slice_middle_three: &mut [i32] = &mut data[4..7];\n",
|
||
" zero(slice_middle_three);\n",
|
||
" print(&data, \"data\");\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 102,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"working_days: [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\"]\n",
|
||
"weekend: [\"Saturday\", \"Sunday\"]\n",
|
||
"days: [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"fn main() {\n",
|
||
" let days = [\"Monday\".to_string(), \"Tuesday\".to_string(), \"Wednesday\".to_string(), \"Thursday\".to_string(), \"Friday\".to_string(), \"Saturday\".to_string(), \"Sunday\".to_string()];\n",
|
||
"\n",
|
||
" let working_days = &days[..5];\n",
|
||
" println!(\"working_days: {:?}\", working_days);\n",
|
||
"\n",
|
||
" let weekend: &[String] = &days[5..];\n",
|
||
" println!(\"weekend: {:?}\", weekend);\n",
|
||
"\n",
|
||
" println!(\"days: {:?}\", days);\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Accessing Slice Elements"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"20\n",
|
||
"30\n",
|
||
"40\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"fn main() {\n",
|
||
" let data: [i32; 5] = [10, 20, 30, 40, 50];\n",
|
||
" let slice: &[i32] = &data[1..4];\n",
|
||
"\n",
|
||
" // Accessing elements by index\n",
|
||
" let second_element = slice[0];\n",
|
||
" assert!(second_element == 20);\n",
|
||
"\n",
|
||
" // Accessing elements by get method\n",
|
||
" let third_element: Option<&i32> = slice.get(2);\n",
|
||
" assert!(third_element == Some(&40));\n",
|
||
"\n",
|
||
" // Accessing elements by iteration\n",
|
||
" for item in slice {\n",
|
||
" println!(\"{}\", item);\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Modifing Slice Elements"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 105,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n",
|
||
"data: [-1, -2, -3, -4, -5, 6, 7, 8, 9, 10]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"fn negate(data: &mut[i32]) {\n",
|
||
" for item in data {\n",
|
||
" *item = -*item;\n",
|
||
" }\n",
|
||
"}\n",
|
||
"\n",
|
||
"\n",
|
||
"fn main() {\n",
|
||
" let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n",
|
||
" println!(\"data: {:?}\", data);\n",
|
||
"\n",
|
||
" let n = data.len()/2;\n",
|
||
" negate(&mut data[0..n]);\n",
|
||
" \n",
|
||
" println!(\"data: {:?}\", data);\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## String Types"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### String Literals"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 106,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"And now \"something\" completely different...\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"let text: &str = \"And now \\\"something\\\" completely different...\\n\";\n",
|
||
"\n",
|
||
"print!(\"{text}\");"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* raw string literals - `r\"...\"`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 107,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let default_win_install_path: &str = r\"C:\\Program Files\\Gorillas\";\n",
|
||
"\n",
|
||
"let regex_pattern: &str = r\"\\d+(\\.\\d+)*\";"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 108,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"\n",
|
||
" This raw string started with 'r###\"'.\n",
|
||
" Therefore it does not end until we reach a quote mark ('\"')\n",
|
||
" followed immediately by three pound signs ('###'):\n",
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"println!(r###\"\n",
|
||
" This raw string started with 'r###\"'.\n",
|
||
" Therefore it does not end until we reach a quote mark ('\"')\n",
|
||
" followed immediately by three pound signs ('###'):\n",
|
||
"\"###);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Byte Strings"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"vscode": {
|
||
"languageId": "rust"
|
||
}
|
||
},
|
||
"source": [
|
||
"* A string literal with the `b` prefix is a **byte string**. \n",
|
||
"* Raw byte strings start with `br\"`\n",
|
||
"* Such a string is a slice of `u8` values—that is, bytes—rather than Unicode text:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 109,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let method: &[u8; 3] = b\"GET\";\n",
|
||
"assert_eq!(method, &[b'G', b'E', b'T']);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Strings in Memory"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"**Rust strings are sequences of Unicode characters**, but they are not stored in memory as arrays of chars. \n",
|
||
"\n",
|
||
"Instead, they are stored using UTF-8, a variable-width encoding. Each ASCII character in a string is stored in one byte. Other characters take up multiple bytes."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 110,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"()"
|
||
]
|
||
},
|
||
"execution_count": 110,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"{\n",
|
||
" let noodles = \"noodles\".to_string();\n",
|
||
" let oodles = &noodles[1..];\n",
|
||
" let poodles = \"ಠ_ಠ\";\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### `&str`\n",
|
||
"\n",
|
||
"* A `&str` (pronounced “stir” or “string slice”) is a reference to a run of UTF-8 text owned by someone else: it “borrows” the text\n",
|
||
"* It is a **fat pointer**, containing both the address of the actual data and its length - `&str` is nothing more than a `&[u8]` that is guaranteed to hold well-formed UTF-8\n",
|
||
"* A string literal is a `&str` that refers to preallocated text, typically stored in read-only memory along with the program’s machine code\n",
|
||
"* It is impossible to modify a `&str`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 113,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"ename": "Error",
|
||
"evalue": "the type `str` cannot be indexed by `{integer}`",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m[E0277] Error:\u001b[0m the type `str` cannot be indexed by `{integer}`",
|
||
" \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0m command_113:1:1 \u001b[38;5;246m]\u001b[0m",
|
||
" \u001b[38;5;246m│\u001b[0m",
|
||
" \u001b[38;5;246m2 │\u001b[0m \u001b[38;5;249mt\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m[\u001b[0m\u001b[38;5;54m0\u001b[0m\u001b[38;5;249m]\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m=\u001b[0m\u001b[38;5;249m \u001b[0m\u001b[38;5;249m'\u001b[0m\u001b[38;5;249mH\u001b[0m\u001b[38;5;249m'\u001b[0m\u001b[38;5;249m;\u001b[0m",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m┬\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m string indices are ranges of `usize`",
|
||
"\u001b[38;5;246m───╯\u001b[0m"
|
||
]
|
||
},
|
||
{
|
||
"ename": "Error",
|
||
"evalue": "no method named `push` found for reference `&str` in the current scope",
|
||
"output_type": "error",
|
||
"traceback": [
|
||
"\u001b[31m[E0599] Error:\u001b[0m no method named `push` found for reference `&str` in the current scope",
|
||
" \u001b[38;5;246m╭\u001b[0m\u001b[38;5;246m─\u001b[0m\u001b[38;5;246m[\u001b[0m command_113:1:1 \u001b[38;5;246m]\u001b[0m",
|
||
" \u001b[38;5;246m│\u001b[0m",
|
||
" \u001b[38;5;246m3 │\u001b[0m \u001b[38;5;249mt\u001b[0m\u001b[38;5;249me\u001b[0m\u001b[38;5;249mx\u001b[0m\u001b[38;5;249mt\u001b[0m\u001b[38;5;249m.\u001b[0m\u001b[38;5;54mp\u001b[0m\u001b[38;5;54mu\u001b[0m\u001b[38;5;54ms\u001b[0m\u001b[38;5;54mh\u001b[0m\u001b[38;5;249m(\u001b[0m\u001b[38;5;249m'\u001b[0m\u001b[38;5;249m\\\u001b[0m\u001b[38;5;249mn\u001b[0m\u001b[38;5;249m'\u001b[0m\u001b[38;5;249m)\u001b[0m\u001b[38;5;249m;\u001b[0m",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m┬\u001b[0m\u001b[38;5;54m─\u001b[0m ",
|
||
" \u001b[38;5;240m │\u001b[0m \u001b[38;5;54m╰\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m\u001b[38;5;54m─\u001b[0m method not found in `&str`",
|
||
"\u001b[38;5;246m───╯\u001b[0m"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut text = \"hello\";\n",
|
||
"text[0] = 'H';\n",
|
||
"text.push('\\n');"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* A `String` or `&str`’s .`len()` method returns its length. The length is measured in bytes, not characters:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 52,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"assert_eq!(\"ಠ_ಠ\".len(), 7);\n",
|
||
"assert_eq!(\"ಠ_ಠ\".chars().count(), 3);\n",
|
||
"\n",
|
||
"\n",
|
||
"let first_char = \"ಠ_ಠ\".chars().nth(0).unwrap();\n",
|
||
"assert_eq!(first_char, 'ಠ');"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### `String`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* A `String` has a resizable buffer holding UTF-8 text. \n",
|
||
"* The buffer is allocated on the heap, so it can resize its buffer as needed or requested. \n",
|
||
"* You can think of a `String` as a `Vec<u8>` that is guaranteed to hold well-formed UTF-8; in fact, this is how `String` is implemented."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Creating Strings"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Creating an empty `String` with `String::new()`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 121,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let empty_string = String::new();\n",
|
||
"assert_eq!(empty_string.len(), 0);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Converting &str to String with `to_string()` or `String::from()` or `into()`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let error_message: String = \"too many arguments\".to_string();\n",
|
||
"let warning_message: String = String::from(\"deprecated function\");\n",
|
||
"let info_message: String = \"operation successful\".into();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Using `format!` to create formatted strings"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"let location = format!(\"{}°{:02}′{:02}″N\", 24, 5, 23);\n",
|
||
"assert_eq!(location, \"24°05′23″N\".to_string());"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* Concatenating vector of strings with `concat()` or `join()`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"\"venividivici\""
|
||
]
|
||
},
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let words: Vec<&str> = vec![\"veni\", \"vidi\", \"vici\"];\n",
|
||
"words.concat()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"\"veni, vidi, vici\""
|
||
]
|
||
},
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"words.join(\", \")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"* If you have a vector of UTF-8 bytes, you can create a `String` from it with the from_utf8 method:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 120,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"💖\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"// some bytes, in a vector\n",
|
||
"let sparkle_heart = vec![240, 159, 146, 150];\n",
|
||
"\n",
|
||
"// We know these bytes are valid, so we'll use `unwrap()`.\n",
|
||
"let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();\n",
|
||
"\n",
|
||
"assert_eq!(\"💖\", sparkle_heart);\n",
|
||
"\n",
|
||
"println!(\"{}\", sparkle_heart);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### String like Vec"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 57,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"\"one!\\ntwo!\\nthree!\\n\""
|
||
]
|
||
},
|
||
"execution_count": 57,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"let mut text = \"one\".to_string();\n",
|
||
"\n",
|
||
"text.push('!');\n",
|
||
"text.push('\\n');\n",
|
||
"text.push_str(\"two!\\n\");\n",
|
||
"text.push_str(\"three!\\n\");\n",
|
||
"\n",
|
||
"text"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 58,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"\"one!\\ntwo!\\nthree!\""
|
||
]
|
||
},
|
||
"execution_count": 58,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"text.pop();\n",
|
||
"text"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"| | Vec<T> | String |\n",
|
||
"| ------------------------------------------------ | ------------------- | ------------------- |\n",
|
||
"| Automatically frees buffers | Yes | Yes |\n",
|
||
"| Growable | Yes | Yes |\n",
|
||
"| `::new()` and `::with_capacity()` static methods | Yes | Yes |\n",
|
||
"| `.reserve()` and `.capacity()` methods | Yes | Yes |\n",
|
||
"| `.push()` and `.pop()` methods | Yes | Yes |\n",
|
||
"| Range syntax `v[start..stop]` | Yes, returns `&[T]` | Yes, returns `&str` |\n",
|
||
"| Automatic conversion | `&Vec<T>` to `&[T]` | `&String` to `&str` |\n",
|
||
"| Inherits methods | From `&[T]` | From `&str` |"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Comparing Strings\n",
|
||
"\n",
|
||
"* Strings support the `==` and `!=` operators"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 59,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"assert!(\"ONE\".to_lowercase() == \"one\");"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Deref\n",
|
||
"\n",
|
||
"* String implements `Deref<Target=str>`, and so inherits all methods `str`\n",
|
||
"* You can use string slices (`&str`) and `String` interchangeably in many cases\n",
|
||
"* You can also pass a `&String` where a `&str` is expected"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"\"Rusty Cage\"\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"fn takes_str(text: &str) {\n",
|
||
" println!(\"{:?}\", text);\n",
|
||
"}\n",
|
||
"\n",
|
||
"let s = String::from(\"Rusty Cage\");\n",
|
||
"takes_str(&s);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Using Strings"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 60,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"veni\n",
|
||
"vidi\n",
|
||
"vici\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"()"
|
||
]
|
||
},
|
||
"execution_count": 60,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"assert!(\"peanut\".contains(\"nut\"));\n",
|
||
"assert_eq!(\"ಠ_ಠ\".replace(\"ಠ\", \"■\"), \"■_■\");\n",
|
||
"assert_eq!(\" clean\\n\".trim(), \"clean\");\n",
|
||
"\n",
|
||
"for word in \"veni, vidi, vici\".split(\", \") {\n",
|
||
" assert!(word.starts_with(\"v\"));\n",
|
||
" println!(\"{word}\");\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Other String Like Types\n",
|
||
"\n",
|
||
"Rust’s solution is to offer a few string-like types for these situations:\n",
|
||
"\n",
|
||
"* Stick to `String` and `&str` for Unicode text.\n",
|
||
"* When working with filenames, use `std::path::PathBuf` and `&Path` instead.\n",
|
||
"* When working with binary data that isn’t character data at all, use `Vec<u8>` and `&[u8]`.\n",
|
||
"* When working with environment variable names and command-line arguments in the native form presented by the operating system, use `OsString` and `&OsStr`.\n",
|
||
"* When interoperating with C libraries that use null-terminated strings, use `std::ffi::CString` and `&CStr`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Real-World Examples"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### String Manipulation"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"File extension: txt\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"let filename = \"example.txt\";\n",
|
||
"let extension: &str = &filename[filename.len() - 3..];\n",
|
||
"println!(\"File extension: {}\", extension);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Data Processing"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Average: 2.62\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"fn calculate_average(slice: &[f64]) -> f64 {\n",
|
||
" let sum: f64 = slice.iter().sum();\n",
|
||
" sum / slice.len() as f64\n",
|
||
"}\n",
|
||
"\n",
|
||
"fn main() {\n",
|
||
" let data: [f64; 6] = [2.5, 3.0, 1.5, 4.0, 2.0, 3.5];\n",
|
||
" let slice: &[f64] = &data[1..5];\n",
|
||
" let average = calculate_average(slice);\n",
|
||
" println!(\"Average: {:.2}\", average);\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Text Tokenization"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Words: [\"Rust\", \"is\", \"a\", \"systems\", \"programming\", \"language.\"]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"fn tokenize_sentence(sentence: &str) -> Vec<&str> {\n",
|
||
" sentence.split_whitespace().collect()\n",
|
||
"}\n",
|
||
"\n",
|
||
"let text: &str = \"Rust is a systems programming language.\";\n",
|
||
"let words = tokenize_sentence(text);\n",
|
||
"println!(\"Words: {:?}\", words);"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Binary Data Handling"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"fn parse_header(header_data: &[u8]) {\n",
|
||
" // Parse the binary header data here\n",
|
||
"}\n",
|
||
"\n",
|
||
"fn main() {\n",
|
||
" let binary_data: [u8; 16] = [0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x52, 0x75, 0x73, 0x74, 0x21, 0x00, 0x00, 0x0A, 0x0D];\n",
|
||
" let header_slice: &[u8] = &binary_data[0..8];\n",
|
||
" parse_header(header_slice);\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Memory mapping"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Read 30 bytes: [84, 104, 105, 115, 32, 105, 115, 32, 97, 32, 102, 105, 108, 101, 32, 119, 105, 116, 104, 32, 115, 111, 109, 101, 32, 116, 101, 120, 116, 46]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"use std::fs::File;\n",
|
||
"use std::io::{self, Read};\n",
|
||
"\n",
|
||
"fn main() -> io::Result<()> {\n",
|
||
" let mut file = File::open(\"file.txt\")?;\n",
|
||
" let mut buffer = [0; 1024];\n",
|
||
"\n",
|
||
" // read a portion of the file to the buffer\n",
|
||
" let bytes_read = file.read(&mut buffer)?;\n",
|
||
"\n",
|
||
" // process the buffer as a slice\n",
|
||
" let slice = &buffer[0..bytes_read];\n",
|
||
" println!(\"Read {} bytes: {:?}\", bytes_read, slice);\n",
|
||
"\n",
|
||
" Ok(())\n",
|
||
"}\n",
|
||
"\n",
|
||
"main();"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Rust",
|
||
"language": "rust",
|
||
"name": "rust"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": "rust",
|
||
"file_extension": ".rs",
|
||
"mimetype": "text/rust",
|
||
"name": "rust",
|
||
"pygment_lexer": "rust",
|
||
"version": ""
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
}
|