Rust Programming Cookbook
Explore the latest features of Rust 2018 for building fast and secure apps
Claus Matzinger
- 444 páginas
- English
- ePUB (apto para móviles)
- Disponible en iOS y Android
Rust Programming Cookbook
Explore the latest features of Rust 2018 for building fast and secure apps
Claus Matzinger
Información del libro
Practical solutions to overcome challenges in creating console and web applications and working with systems-level and embedded code, network programming, deep neural networks, and much more.
Key Features
- Work through recipes featuring advanced concepts such as concurrency, unsafe code, and macros to migrate your codebase to the Rust programming language
- Learn how to run machine learning models with Rust
- Explore error handling, macros, and modularization to write maintainable code
Book Description
Rust 2018, Rust's first major milestone since version 1.0, brings more advancement in the Rust language. The Rust Programming Cookbook is a practical guide to help you overcome challenges when writing Rust code.
This Rust book covers recipes for configuring Rust for different environments and architectural designs, and provides solutions to practical problems. It will also take you through Rust's core concepts, enabling you to create efficient, high-performance applications that use features such as zero-cost abstractions and improved memory management. As you progress, you'll delve into more advanced topics, including channels and actors, for building scalable, production-grade applications, and even get to grips with error handling, macros, and modularization to write maintainable code. You will then learn how to overcome common roadblocks when using Rust for systems programming, IoT, web development, and network programming. Finally, you'll discover what Rust 2018 has to offer for embedded programmers.
By the end of the book, you'll have learned how to build fast and safe applications and services using Rust.
What you will learn
- Understand how Rust provides unique solutions to solve system programming language problems
- Grasp the core concepts of Rust to develop fast and safe applications
- Explore the possibility of integrating Rust units into existing applications for improved efficiency
- Discover how to achieve better parallelism and security with Rust
- Write Python extensions in Rust
- Compile external assembly files and use the Foreign Function Interface (FFI)
- Build web applications and services using Rust for high performance
Who this book is for
The Rust cookbook is for software developers looking to enhance their knowledge of Rust and leverage its features using modern programming practices. Familiarity with Rust language is expected to get the most out of this book.
Preguntas frecuentes
Información
Getting Practical with Rust
- Random number generation
- File I/O
- Dynamic JSON
- Regular expressions
- Filesystem access
- Command-line arguments
- Piping input and output
- Web requests
- Using state-of-the-art machine learning libraries
- Logging
- Starting subprocesses
Generating random numbers
How to do it...
- Open a Terminal to create a new project using cargo new random-numbers --lib. Use VS Code to open the project directory.
- First, we need to add the rand crate as a dependency in Cargo.toml. Open it to add the following:
[dependencies]
rand = {version = "0.7", features = ["small_rng"]}
rand_distr = "0.2"
rand_pcg = "0.2"
- Since we are exploring how to use the rand library, we are going to add to the test module and implement three tests. Let's start by replacing the default content in src/lib.rs with some required imports:
#[cfg(test)]
mod tests {
use rand::prelude::*;
use rand::SeedableRng;
use rand_distr::{Bernoulli, Distribution, Normal, Uniform};
}
- Right underneath the imports (inside the mod tests scope), we are going to add the first test to check how Random Number Generators (RNGs) and Pseudo-Random Number Generators (PRNGs) work. To have predictable random numbers, we make every generator based on the first, which uses an array literal for initialization:
#[test]
fn test_rngs() {
let mut rng: StdRng = SeedableRng::from_seed([42;32]);
assert_eq!(rng.gen::<u8>(), 152);
let mut small_rng = SmallRng::from_rng(&mut rng).unwrap();
assert_eq!(small_rng.gen::<u8>(), 174);
let mut pcg = rand_pcg::Pcg32::from_rng(&mut rng).unwrap();
assert_eq!(pcg.gen::<u8>(), 135);
}
- Having seen regular (P)RNGs, we can move on to something more sophisticated. How about using these RNGs to operate on sequences? Let's add this test that uses PRNGs to do a shuffle and pick results:
#[test]
fn test_sequences() {
let mut rng: StdRng = SeedableRng::from_seed([42;32]);
let emoji = "ABCDEF".chars();
let chosen_one = emoji.clone().choose(&mut rng).unwrap();
assert_eq!(chosen_one, 'B');
let chosen = emoji.choose_multiple(&mut rng, 3);
assert_eq!(chosen, ['F', 'B', 'E']);
let mut three_wise_monkeys = vec!['1', '2', '3'];
three_wise_monkeys.shuffle(&mut rng);
three_wise_monkeys.shuffle(&mut rng);
assert_eq!(three_wise_monkeys, ['1', '3', '2']);
let mut three_wise_monkeys = vec!['1', '2', '3'];
let partial = three_wise_monkeys.partial_shuffle(&mut rng, 2);
assert_eq!(partial.0, ['3', '2']);
}
- As we stated in this recipe's introduction, RNGs can follow a distribution. Now, let's add another test to the tests module to draw random numbers that follow a distribution using the rand crate:
const SAMPLES: usize = 10_000;
#[test]
fn test_distributions() {
let mut rng: StdRng = SeedableRng::from_seed([42;32]);
let uniform = Uniform::new_inclusive(1, 100);
let total_uniform: u32 = uniform.sample_iter(&mut rng)
.take(SAMPLES).sum();
assert!((50.0 - (total_uniform as f32 / (
SAMPLES as f32)).round()).abs() <= 2.0);
let bernoulli = Bernoulli::new(0.8).unwrap();
let total_bernoulli: usize = bernoulli
.sample_iter(&mut rng)
.take(SAMPLES)
.filter(|s| *s)
.count();
assert_eq!(
((total_bernoulli as f32 / SAMPLES as f32) * 10.0)
.round()
.trunc(),
8.0
);
let normal = Normal::new(2.0, 0.5).unwrap();
let total_normal: f32 = normal.sample_iter(&mut rng)
.take(SAMPLES).sum();
assert_eq!((total_normal / (SAMPLES as f32)).round(), 2.0);
}
- Lastly, we can run the tests to see whether the test outputs positive results:
$ cargo test
Compiling random-numbers v0.1.0 (Rust-Cookbook/Chapter10/random-numbers)
Finished dev [unoptimized + debuginfo] target(s) in 0.56s
Running target/debug/deps/random_numbers-df3e1bbb371b7353
running 3 tests
test tests::test_sequences ... ok
test tests::test_rngs ... ok
test tests::test_distributions ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests random-numbers
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
How it works...
Popular seeds include seconds since 1 Jan 1970, entropy by the OS, user input, and more. The less predictable it is, the better.