CS代考 CIS 198](https://www.cis.upenn.edu/~cis198/)

## Reference

– [The Rust Programming Language](https://doc.rust-lang.org/book/) (TRPL)
– [UPenn CIS 198](https://www.cis.upenn.edu/~cis198/)

Copyright By PowCoder代写 加微信 powcoder

– [ Patterns](https://rust-unofficial.github.io/patterns/)

# 09/03 Lecture 1

In the first class, we should first do course introduction. it will take about 10 minutes.

Then, we will introdu the basic ideas in rust. I will follow TRPL to do this, which means I will introduce
1. install/update `rustc`
2. cargo basics
3. variables and mutability
4. data types
5. comments
6. control flow

## [Course introduction](http://www.cs.umd.edu/class/fall2021/cmsc388Z/)

## Why Rust?

“Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.”

In other words: Rust is designed for speed, safety, and concurrency.

#### What is “Systems Programming”?

Areas of systems programming:
– Operating Systems
– Device Drivers
– Embedded Systems
– Real Time Systems
– Networking
– Virtualization and Containerization
– Scientific Computing
– Video Games

Other systems languages include: C, C++, Ada, D.

Like C and C++, Rust gives developers fine control over the use of memory, and maintains a close relationship between the primitive operations of the language and those of the machines it runs on, helping developers anticipate the costs (time and space) of operations.

#### Who uses Rust?

– [Amazon](https://aws.amazon.com/blogs/aws/firecracker-lightweight-virtualization-for-serverless-computing)
– [Facebook](https://developers.libra.org/)
– [Firefox](https://servo.org)
– [Discord](https://blog.discord.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f)
– [Dropbox](https://dropbox.tech/infrastructure/rewriting-the-heart-of-our-sync-engine)
– [Coursera](https://medium.com/coursera-engineering/rust-docker-in-production-coursera-f7841d88e6ed)

“For five years running, Rust has taken the top spot as [the most loved programming language](https://insights.stackoverflow.com/survey/2020#technology-most-loved-dreaded-and-wanted-languages-loved).”

Now a [top 20 language](https://www.reddit.com/r/rust/comments/hz7dfp/rust_is_now_a_top_20_language_in_all_of_the_5/) in most language popularity rankings, and one of the fastest-growing:
[Second most used language](https://app.powerbi.com/view?r=eyJrIjoiZTQ3OTlmNDgtYmZlMS00ZTJmLTkwYTgtMWQyMTkxNWI5NGM1IiwidCI6IjQwOTEzYjA4LTQyZTYtNGMxOS05Y2FiLTRmOWZlM2U0YzJmZCIsImMiOjl9) for Advent of Code this year, after Python:
#### Why Rust?

– Safe -> statically typed, and compile time checked for memory safety
– Trustworthy concurrency

In particular, Rust’s goals of memory safety and trustworthy concurrency are what makes it most unique. These concepts — in particular the issues surrounding data ownership — can be both the most surprising and the most rewarding parts of learning Rust.

### Type Safety and Memory Safety

A language is said to be [memory-safe](https://www.zdnet.com/article/microsoft-70-percent-of-all-security-bugs-are-memory-safety-issues/) if all programs written in that language have defined semantics for all possible states.

#### Aside: [Typing](https://medium.com/android-news/magic-lies-here-statically-typed-vs-dynamically-typed-languages-d151c7f95e2b)
**Rust is a [type safe and statically typed](http://www.cs.umd.edu/class/spring2021/cmsc330/lectures/26-types.pdf) language:**

**C and C++ are not type safe!** Undefined Behavior is the root of all evil.

#### Undefined Behavior

– buffer overruns.
Your program will access elements beyond the end or before the start of an array.

int main() {
int x = 1, *p = &x;
int y = 0, *q = &y;
*(q+1) = 5; // overwrites p
return *p; // crash

– dangling pointers (uses of pointers to freed memory)

… which can happen via the stack, too:

int *foo(void) { int z = 5; return &z; }
void bar(void) {
int *x = foo();
*x = 5; /* oops! */

[Heartbleed](https://xkcd.com/1354/).

– Problem: C and C++ allow for direct memory dereference, no checking.
Systems languages are what we built everything on top of! Even other languages are built on top of C and C++:
– Java Virtual Machine

**Why then, do we not check things at runtime?**

#### Null References — Billion Dollar Mistake

> I call it my billion-dollar mistake. It was the invention of the null reference in 1965… My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. [name= ]

### Performance

– **Zero Cost Abstraction:** In general, C++ and rust implementations obey the zero-overhead principle:
What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better.

Rust performs similar (even [slightly better](https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-gpp.html)) than C++.

### Concurrency

– Computers are multicore, need for parallelism.\
![](https://www.karlrupp.net/wp-content/uploads/2015/06/35years.png)

– Concurrency is hard:
https://en.wikipedia.org/wiki/Therac-25

– No data race in rust (achieved by ownership)
### Examples of

No null pointer dereferences. (Not unique to Rust)

Your program will not crash because you tried to dereference a null pointer.

The problems with null
1) Used to represent a missing value:
`String getValue(HashTable t)`;
3) Use to represent an error:
`void* malloc(size_t size)`
5) It is very easy to ignore.

// Optional Values:
enum Option

{

Still compiles down to pointer and null! But to use the value, one need to unwrap the value from `Option

`.

#### Handling Possible Errors

enum Result {

fn read(&mut fd: FileDescriptor, buf: &mut [u8]) -> Result;

#### Memory Management
– **C and C++**: Manual memory management.
– **Python and Java**: Automatic Memory Management via a garbage collector.
– A garbage collector traces pointers in use by the program, starting from the stack and global variables.
– Drawback: Time critical code, performance, runtime/portability
– **Rust**:
– [Reference counting]() + [Non-Lexical Lifetimes](http://blog.pnkfx.org/blog/2019/06/26/breaking-news-non-lexical-lifetimes-arrives-for-everyone/#How.was.NLL.implemented)
– Fast, safe and smart.

## Rust install/update

To check whether you have Rust installed correctly, run this in your terminal:

$ rustc –version

you will see the version number

$ rustc 1.54.0 (a178d0322 2021-07-26)

If you have different version or you don’t have rust installed:

– If you have not installed Rust in your computer, install it through [Rust-lang website](https://www.rust-lang.org/tools/install).
– If you have it installed in your computer, update it!

$ rustup update stable

To play with Rust online in your browser, go rust-lang playground (https://play.rust-lang.org).

## Hello Cargo

Cargo is Rust’s build system and package manager. Cargo comes installed with Rust if you used the official installers described above and in [TRPL](https://doc.rust-lang.org/book/ch01-01-installation.html#installation). Cargo is so frequently used so it has its own [book](https://doc.rust-lang.org/cargo/)! After installing Rust, You can check your Cargo version by:

$ cargo –version

Cargo integrated many useful commands to help you manage your projects. You can create, run, build, check and test your project with cargo’s easy commands!

– Creating a Project with Cargo

$ cargo new hello_cargo
$ cd hello_cargo

– Building and Running a Cargo Project
$ cargo build

$ cargo run

– Building for Release
$ cargo build –release

– Check the format of your code
$ cargo fmt

– check the syntax of your code
$ cargo clippy

### build a project from GitHub

$ git clone example.org/someproject
$ cd someproject
$ cargo build

## Hello VSCode

I suggest you to write your rust code in [VS code](https://code.visualstudio.com/) with `rust-analyzer` [extention](https://github.com/rust-analyzer/rust-analyzer).

## Hello world!

Create a `hello_world` rust project using Cargo:

cargo new hello_world
cd hello_world

You folder will contain the following files.
No `code` command on mac? [Here](https://code.visualstudio.com/docs/setup/mac) is the solution. \
![](https://i.imgur.com/drZJnCp.png)

– `src/main.rs`\
![](https://i.imgur.com/ihD1LeT.png)

– `Cargo.toml`\
![](https://i.imgur.com/h1GmfSI.png)

#### check fmt

– Check the format of your code
$ cargo fmt

If you add some empty line in the `main()`, `cargo fmt` will clean it for you.

#### clippy it!

$ cargo clippy

if you define an unused variable, for example

fn main() {
let a = 1;
println!(“Hello, world!”);

`cargo clippy` will complain.

### Run it!

### Build it

#### Build release
– Building for Release
$ cargo build –release

## Common Programming Concepts

### Variables and Mutability

In rust, variables are defined via keyword `let`. By default, variables are immutable, except you specify it.

fn main() {
let x = 37;
let y = x + 5;

fn main() {
let x = 37;
x = x + 5;//err

fn main() {//err:
let x:u32 = -1;
let y = x + 5;

fn main() {
let x = 37;
let x = x + 5;

fn main() {
let mut x = 37;
x = x + 5;

fn main() {
let x:i16 = -1;
let y:i16 = x+5;

### Differences Between Variables and Constants

#![allow(unused)]
fn main() {
const MAX_POINTS: u32 = 100_000;

1. constants are defined using the `const` keyword.
2. You are not allowed to `mut` constants.
3. You **must** annotate the type of constants.
4. Constants are valid for the entire time a program runs, within the scope they were declared in.
5. constants cannot be set as the result of a functional call or any other value that could only be computed at runtime.

### Shadowing

fn main() {
let x = 5;

let x = x + 1;

let x = x * 2;

println!(“The value of x is: {}”, x);
The result will be `12`.

Shadowing is useful if
1. a value needs a few modifications in the whole program
2. we want to change the type of the value but reuse the same name.

let spaces = ” “;
let spaces = spaces.len();

but rust will complain if we do

let mut spaces = ” “;
spaces = spaces.len();

because we want to change the value of the variable as well.

### Data Type

#### Scalar Types
A scalar type represents a single value. Rust has four primary scalar types:

##### 1. integers
![](https://i.imgur.com/nYmQio1.png)
The `isize` and `usize` types depend on the kind of computer your program is running on: 64 bits if you’re on a 64-bit architecture and 32 bits if you’re on a 32-bit architecture.

You can write integer literals in any of the forms below. Note that all number literals except the byte literal allow a type suffix, such as 57u8, and _ as a visual separator, such as 1_000.

##### 2. floating-point numbers

fn main() {
let x = 2.0; // f64, default

let y: f32 = 3.0; // f32

##### Numeric Operations

fn main() {
// addition
let sum = 5 + 10;

// subtraction
let difference = 95.5 – 4.3;

// multiplication
let product = 4 * 30;

// division
let quotient = 56.7 / 32.2;

// remainder
let remainder = 43 % 5;

4. Booleans

fn main() {
let t = true;

let f: bool = false; // with explicit type annotation
The main way to use Boolean values is through conditionals, such as an if expression.

6. characters

fn main() {
let c = ‘z’;
let z = ‘ℤ’;
let heart_eyed_cat = ‘😻’;

Rust’s `char` type is four bytes in size and represents a Unicode Scalar Value, which means it can represent a lot more than just ASCII. Accented letters; Chinese, Japanese, and Korean characters; emoji; and zero-width spaces are all valid `char` values in Rust. Unicode Scalar Values range from `U+0000` to `U+D7FF` and `U+E000` to `U+10FFFF` inclusive. However, a “character” isn’t really a concept in Unicode, so your human intuition for what a “character” is may not match up with what a char is in Rust.

#### Compound Types

Compound types can group multiple values into one type. Rust has two primitive compound types: tuples and arrays.

##### The Tuple Type

A tuple is a general way of grouping together a number of values with a variety of types into one compound type. **Tuples have a fixed length**: once declared, they cannot grow or shrink in size. Tuple will be allocated on the stack.

fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);

**destructuring**

In addition to destructuring through pattern matching, we can access a tuple element directly by using a period (`.`) followed by the index of the value we want to access. For example:
fn main() {
let tup = (500, 6.4, 1);

let (x, y, z) = tup;

println!(“The value of y is: {}”, y);

This program creates a tuple, `x`, and then makes new variables for each element by using their respective indices. As with most programming languages, the first index in a tuple is 0.

##### The Array Type

Another way to have a collection of multiple values is with an array. Unlike a tuple, every element of an array **must have the same type**. Arrays in Rust are different from arrays in some other languages because arrays in Rust have a **fixed length**, like tuples.

1. Creating an array
fn main() {
let a: [i32; 5] = [1, 2, 3, 4, 5];

Here, `i32` is the type of each element. After the semicolon, the number `5` indicates the array contains five elements.

let a = [3; 5];

The array named `a` will contain `5` elements that will all be set to the value `3` initially. This is the same as writing `let a = [3, 3, 3, 3, 3]`; but in a more concise way.

2. Accessing array elements
An array is a single chunk of memory allocated on the stack. You can access elements of an array using indexing, like this:
pub fn array() {
// Size is hardcoded for arrays.
// There space is allocated directly in the binary.
let a = [1, 2, 3];
let zeroes = [0; 1000];
let b: [i32; 3] = [1, 2, 3];

// Typical example
let input_files = [“input/input_1.txt”, “input/input_2.txt”];

let first = a[0];
let second = a[1];
// println!(“{:?}”, a + a);
// a.push(3);

3. Buffer overflow?
**NEVER**. Rust checks the bounds at both compile time and run time. You will get an OOB error.

#### Statements and Expressions
– Statements are instructions that perform some action and **do not return a value. **
– Expressions evaluate to a resulting value.

// function body
fn main() {
let x = 5; // statement

let x = 3; // statement
x + 1 // expression
}; // statement

println!(“The value of y is: {}”, y); // statement

In the function body, this block is an expression.

let x = 3; // statement
x + 1 // expression

### Comments

In each line, everything after a double reversed slash `//` can be used to mark comments.

// I am a comment.
a = 5; // I am also a comment.

Before a function definition, a triple reversed slash `///` can be used to mark the description of a function.

/// I am the description of function `a_function()`.
fn a_function() {}

### Control Flow

fn main() {
let number = 6;

let sign = if number < 0 { } else if number == 0 { #### loops ##### `loop` The loop keyword tells Rust to execute a block of code over and over again forever or until you explicitly tell it to stop. fn main() { println!("again!"); ##### `while` fn main() { let mut number = 3; while number != 0 { println!("{}!", number); number -= 1; println!("LIFTOFF!!!"); ##### `for` fn main() { let a = [10, 20, 30, 40, 50]; let mut index = 0; while index < 5 { println!("the value is: {}", a[index]); index += 1; Rust provides a way to **iterate** over a collection fn main() { let a = [10, 20, 30, 40, 50]; for element in a.iter() { println!("the value is: {}", element); If you know exactly which elements you want to iterate, used `Range`: fn main() { let a = [10, 20, 30, 40, 50]; for element in (1..4).rev() { println!("the value is: {}", element); ## Testing In any language, there is the need to test code. In most languages, testing requires extra libraries: - Minitest in Ruby - Ounit in Ocaml - Junit in Java Testing in Rust is a first-class citizen! The testing framework is **built into cargo**. ### Unit testing Unit testing is for local or private functions Put such tests in the same file as your code - Use `assert!` to test that something is true - -Use `assert_eq!` to test that two things that implement the PartialEq trait are equal. - E.g., integers, booleans, etc. fn bad_add(a: i32, b: i32) -> i32 {

#[cfg(test)]
mod tests {
fn test_bad_add () {
assert_eq!(bad_add(1,3),3);

### Integration testing

Integration testing is for APIs and whole programs
(This is how we grade your projects).

– Create a tests directory
– Create different files for testing major functionality
– Files don’t need #[cfg(test)] or a special module
– But they do still need #[test] around each function
– Tests refer to code as if it were an external library
– Declare it as an external library using extern crate
– Include the functionality you want to test with use

`src/lib.rs`
pub fn add(a: i32, b: i32) -> {

`tests/test_add.rs`
extern crate your_project_name // this will tell rust you have an external source
use your_project_name::add; // this will tell rust you will use add() function from the extern source

pub fn test_add () {
assert_eq!(add(1,2),3);

pub fn test_negative_add() {
assert_eq!(add(1,-2),-1);

# Please fill out [this](https://forms.gle/GA37gwAWbwMrB8Zh9) survey!

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com