04. Модули и тестване

04. Модули и тестване

04. Модули и тестване

18 октомври 2017

Административни неща

Въпрос

fn print_length(s: &String) {
    println!("The length of '{:?}' is: {}", s, s.len());
}

let s1 = "Static string";
print_length( /* ??? */ );

let s2 = String::from("Heap-allocated string");
print_length( /* ??? */ );

let s3 = &s2[14..];
print_length( /* ??? */ );

Отговор

fn print_length(s: &String) {
    println!("The length of '{:?}' is: {}", s, s.len());
}

let s1 = "Static string"; // => &str
print_length(&String::from(s1));

let s2 = String::from("Heap-allocated string"); // => String
print_length(&s2);

let s3 = &s2[14..]; // => &str
print_length(&String::from(s3));

Въпрос

fn print_length(s: &str) {
    println!("The length of '{:?}' is: {}", s, s.len());
}

let s1 = "Static string";
print_length( /* ??? */ );

let s2 = String::from("Heap-allocated string");
print_length( /* ??? */ );

let s3 = &s2[14..];
print_length( /* ??? */ );

Отговор

fn print_length(s: &str) {
    println!("The length of '{:?}' is: {}", s, s.len());
}

let s1 = "Static string"; // => &str
print_length(s1);

let s2 = String::from("Heap-allocated string"); // => String
print_length(&s2[..]);
print_length(&s2);

let s3 = &s2[14..]; // => &str
print_length(s3);

Въпрос

fn print_length(l: &[u32]) {
    println!("The length of '{:?}' is: {}", l, l.len());
}

let l1 = [1_u32, 2, 3, 4];
print_length( /* ??? */ );

let l2 = vec![1_u32, 2, 3, 4];
print_length( /* ??? */ );

let l3 = &l2[0..2]; // => &[u32]
print_length( /* ??? */ );

Отговор

fn print_length(l: &[u32]) {
    println!("The length of '{:?}' is: {}", l, l.len());
}

let l1 = [1_u32, 2, 3, 4]; // => [u32; 4];
print_length(&l1);

let l2 = vec![1_u32, 2, 3, 4]; // => Vec<u32>
print_length(&l2);

let l3 = &l2[0..2]; // => &[u32]
print_length(l3);

Deref coercion

println!

println!("{}² + {}² = {}²", 3, 4, 5);

print!("{}² + {}² = {}²\n", 3, 4, 5);

Въпрос: format!

let s = format!("{}² + {}² = {}²", 3, 4, 5);

Въпрос: какво смятате, че е s?

Въпрос: format!

let s = format!("{}² + {}² = {}²", 3, 4, 5);

Модули

Модули

cargo new communicator 

Модули

mod network {
    fn connect() {
        // ...
    }
}

mod client {
    fn connect() {
        // ...
    }
}

Модули

Модули

mod network {
    fn connect() {
        // ...
    }

    mod client {
        fn connect() {
            // ...
        }
    }
}

Модули

Модули

mod network {
    fn connect() { /* ... */ }

    mod client {
        fn connect() { /* ... */ }

        fn init() {
            // извикваме `network::client::connect()`
            connect();
            // client::connect()   // грешка при компилация
        }
    }
}

Модули

mod network {
    fn connect() { /* ... */ }

    mod client {
        fn connect() { /* ... */ }

        fn init() {
            // извикваме `network::connect()`
            ::network::connect();
            super::connect();
            // network::connect()   // грешка при компилация
        }
    }
}

Модули

mod network {
    fn connect() { /* ... */ }

    fn init() {
        // извикваме `network::connect()`
        connect();
        ::network::connect();
    }

    mod client {
        fn connect() { /* ... */ }
    }
}

Модули

mod network {
    fn connect() { /* ... */ }

    fn init() {
        // извикваме `network::client::connect()`
        client::connect();              // ?
        ::network::client::connect();   // ?
    }

    mod client {
        fn connect() { /* ... */ }
    }
}

Модули

error[E0603]: function `connect` is private
  --> src/main.rs:12:9
   |
12 |         client::connect();
   |         ^^^^^^^^^^^^^^^ 

Модули

pub

mod network {
    fn connect() { /* ... */ }

    fn init() {
        // извикваме `network::connect()`
        client::connect();
        ::network::client::connect();
    }

    mod client {
        // добавяме pub
        pub fn connect() { /* ... */ }
    }
}

Модули

pub

mod network {
    mod client {
        pub fn connect() {
            log_debug_statement();
        }

        fn log_debug_statement() {
            println!("client::connect()");
        }
    }
}

Модули

pub

mod network {
    mod client {
        pub fn connect() {
            log_debug_statement();
        }

        fn log_debug_statement() {
            println!("client::connect()");
        }
    }
}

fn main() {
    network::client::connect();     // ?
}

Модули

pub

pub mod network {
    pub mod client {
        pub fn connect() {
            log_debug_statement();
        }

        fn log_debug_statement() {
            println!("client::connect()");
        }
    }
}

fn main() {
    network::client::connect();
}

Модули

файлове

mod client {
    fn connect() { /* ... */ }
}

mod network {
    fn connect() { /* ... */ }

    mod server {
        fn connect() { /* ... */ }
    }
}

Модули

файлове

communicator
├── client
└── network
    └── server 

Модули

файлове

communicator/
├── src/main.rs
├── src/lib.rs
├── src/client.rs
└── src/network/
    ├── mod.rs
    └── server.rs 

Модули

файлове

src/lib.rs

pub mod client;
pub mod network;

Модули

файлове

src/client.rs

// ::client::connect()
pub fn connect() {
    log_debug_statement();
}

fn log_debug_statement() {
    println!("client::connect()");
}

Модули

файлове

src/network/mod.rs

pub mod server;

// ::network::connect()
pub fn connect() {
}

Модули

файлове

src/network/server.rs

// ::network::server::connect()
pub fn connect() {
}

Модули

употреба

src/main.rs

fn main() {
     client::connect();
     network::connect();
     network::server::connect();
}

Модули

употреба

От външен проект:

extern crate communicator;

fn main() {
     communicator::client::connect();
     communicator::network::connect();
     communicator::network::server::connect();

     // communicator::client::log_debug_statement() // => compile-time грешка
}

Модули

use

extern crate communicator;

use communicator::client;
use communicator::network;

fn main() {
     client::connect();
     network::connect();
     network::server::connect();
}

Модули

use

extern crate communicator;

use communicator::{client, network};

fn main() {
     client::connect();
     network::connect();
     network::server::connect();
}

Модули

use

extern crate communicator;

use communicator::client;
use communicator::{self, server};

fn main() {
     client::connect();
     network::connect();
     server::connect();
}

Модули

конфликти с use

extern crate communicator;

use communicator::client::connect;
use communicator::network::connect;

// грешка при компилация

Модули

конфликти с use

extern crate communicator;

use communicator::client::connect as client_connect;
use communicator::network::connect as network_connect;

Атрибути

Атрибути

Синтаксис

Атрибути

Синтаксис

#[test]
fn test_something() {
    // ...
}

Атрибути

Синтаксис

#[derive(Debug, Clone)]
struct User {
    // ...
}

Атрибути

Синтаксис

Някои примери за условна компилация

#[cfg(target_os = "macos")]
struct Client;

#[cfg(any(foo, bar))]
fn bark() { /*...*/ }

#[cfg(all(unix, target_pointer_width = "32"))]
impl Cat {}

#[cfg(not(foo))]
{
    // ...
}

Документация

Атрибут `doc`

Документация

Модули

//! A contiguous growable array type with heap-allocated contents, written
//! `Vec<T>`.
//!
//! Vectors have `O(1)` indexing, amortized `O(1)` push (to the end) and
//! `O(1)` pop (from the end).
//!
//! # Examples
//!
//! You can explicitly create a [`Vec<T>`] with [`new`]:
//!
//! ```
//! let v: Vec<i32> = Vec::new();
//! ```

Документация

/// A UTF-8 encoded, growable string.
///
/// The `String` type is the most common string type that has ownership over the
/// contents of the string. It has a close relationship with its borrowed
/// counterpart, the primitive str.
pub struct String {
    vec: Vec<u8>,
}

Документация

Полета

pub struct String {
    /// Some field comment
    vec: Vec<u8>, /// This does not work
}

Документация

impl String {
    /// Creates a new empty `String`.
    ///
    /// Given that the `String` is empty, this will not allocate any initial
    /// buffer. While that means that this initial operation is very
    /// inexpensive, but may cause excessive allocation later, when you add
    /// data. If you have an idea of how much data the `String` will hold,
    /// consider the [`with_capacity`] method to prevent excessive
    /// re-allocation.
    pub fn new() -> String {
        String { vec: Vec::new() }
    }
}

Документация

Инструменти

Тестове

Тестове

Команди

Тестове

Unit tests

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        // ...
    }
}

Тестове

Unit tests

Тестове

Unit tests

assert!(1 == 2);
assert_eq!(1, 2);

Тестове

Integration tests

project
├── src
└── tests
    └── some_test.rs 
  • папка tests
  • extern crate project
  • не е нужен тест модул

Тестове

Doc tests

/// A string.
///
/// # Examples
///
/// ```
/// let s = String::new();
/// ```
struct String;

Тестове

Doc tests

Тестове

Doc tests types

Торба с неща, които ще ви трябват

Итерация с for

for element in collection.into_iter() {
    //...
}

for element in collection.iter() {
    //...
}

for element in collection.iter_mut() {
    //...
}

Char/Byte

for element in collection.bytes() {
    //...
}

for element in collection.chars() {
    //...
}

Документация за String, &str, char

Първо домашно!

Въпроси