13 - closures Flashcards

1
Q
  1. What are closures?

2. How are they different from functions?

A
  1. Rust’s closures are anonymous functions you can save in a variable or pass as arguments to other functions.
  2. Unlike functions, closures can capture values from the scope in which they’re defined.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is a workspace in Rust?

A

A workspace is a set of packages that share the same Cargo.lock and output directory.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Does Cargo assume that crates in a workspace will depend on each other?

A

No, we need to explicitly tell cargo in the [dependencies] section in the relevant Cargo.toml

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

How to run/test a specific package within a workspace directory?

A

cargo run -p package_name

cargo test -p package_name

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Why do we have only one Cargo.lock file in a workspace, rather than having a Cargo.lock in each crate’s directory?

A

This ensures that all crates are using the same version of all dependencies.
Cargo will resolve the same dependencies in multiple Cargo.toml files to one version and this is recorded n Cargo.lock file.
This is will guarantee that all crates in the workspace will always be compatible with each other.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Where do binaries installed using the cargo install command are stored?

A

They are stored in the installation root’s bin folder.
If you installed Rust using rustup.rs and don’t have any custom configurations, this directory will be $HOME/.cargo/bin.

*Ensure that directory is in your $PATH to be able to run program you’ve installed with cargo install

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Assume you have a binary in your $PATH that is named cargo-something. How can you run that executable from Cargo?
Where does this custom command is listed?

A

You can run it as if it was a Cargo subcommand by running cargo something.
Custom commands like this are listed when you run cargo –list

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

When will you use the Box smart pointer?

A

Typically:

  1. When you have a type whose size can’t be known at compile time and you want to use a value of that type in a context that requires an exact size.
  2. When you have a large amount of data and you want to transfer ownership but ensure the data won’t be copied when you do so.
  3. When you want to own a value and you care only that it’s a type that it’s a type that implements a particular trait rather than being of a specific type.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Why can we use the dereference operator on Box?

A

Because Box implements the Deref trait.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Why do deref() returns a reference instead of the value itself?

A
This has to do with Rust's ownership system.
If deref() method returned the value directly instead of a reference to the value, the value would be moved out of self. In most cases, we don't want to take ownership of the inner value inside the type that implements Deref
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is deref Coercion?

A

Deref coercion is a convenience that Rust performs on arguments to functions and methods. Deref coercion works only on types that implement the Deref trait. It converts such a type into a reference to another type.

For example, it can convert &String into $str

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

When does deref coercion happens?

A

Rust does deref coercion when it finds types and trait implementations in three cases:

  1. From &T to &U when T: Deref
  2. From &mut T to &mut U when T: DerefMut
  3. From &mut T to &U when T: Deref

Deref coercion happens automatically when we pass a reference to a particular type’s value as an argument to a function or method that doesn’t match the parameter type in the function or method definition. A sequence of calls to the deref method converts the type provided into the type the parameter needs.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Can rust perform deref coercion when going from a immutable reference to a mutable reference? Why?

A

No.
The borrowing rules state that you can only have one mutable reference to a specific piece of data within a specific scope.
Converting an immutable reference to a mutable reference would require that the initial immutable reference is the only immutable reference to that data, but the borrowing rules don’t guarantee that.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What two important traits are implemented by smart pointers?

A

The Deref and the Drop traits.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

In what order variables will be dropped? Which var drops first?

A

variables will be dropped in the reverse order of their creation.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Why can’t we call the method drop() for a variable? What can we do instead?

A

Because this would create a double free error (rust is dropping the variable in the end of the scope).
Instead of using a.drop() we can use drop(a).

17
Q

What’s the problem in the following code (not syntax)?

enum List { Cons(i32, Box), Nil }
use crate::List::{Cons, Nil};
fn main() {
  let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));
  let b = Cons(3, Box::new(a));
  let c = Cons(4, Box::new(a));
}
A

The value a was moved into b so it cannot be used again.

*try use reference counting pointer - Rc

18
Q

What is the interior mutability pattern?

A

it is a design pattern in Rust that allows you to mutate data even when there are immutable references to that data (normally, it is disallowed by the borrowing rules).
To mutate data the pattern uses unsafe code inside a data structure to bend Rust’s usual rules that govern mutation and borrowing.

19
Q

What can you do with Rc that holds a RefCell?

A

You can get a value that can have multiple owners and that you can mutate!