2019-03-07 03:47:00 +07:00
# VARIABLES
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "variables1"
2019-03-07 03:47:00 +07:00
path = "exercises/variables/variables1.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
2019-11-14 14:20:38 +07:00
Hint : The declaration on line 12 is missing a keyword that is needed in Rust
2019-11-11 22:51:38 +07:00
to create a new variable binding . "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "variables2"
2019-03-07 03:47:00 +07:00
path = "exercises/variables/variables2.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
The compiler message is saying that Rust cannot infer the type that the
variable binding ` x ` has with what is given here .
2019-11-14 14:20:38 +07:00
What happens if you annotate line 7 with a type annotation ?
2019-11-11 22:51:38 +07:00
What if you give x a value ?
What if you do both ?
What type should x be , anyway ?
What if x is the same type as 10 ? What if it ' s a different type ? "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "variables3"
2019-03-07 03:47:00 +07:00
path = "exercises/variables/variables3.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
In Rust , variable bindings are immutable by default . But here we ' re trying
to reassign a different value to x ! There ' s a keyword we can use to make
a variable binding mutable instead . "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "variables4"
2019-03-07 03:47:00 +07:00
path = "exercises/variables/variables4.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
Oops ! In this exercise , we have a variable binding that we ' ve created on
2019-11-14 14:20:38 +07:00
line 7 , and we 're trying to use it on line 8, but we haven' t given it a
2019-11-11 22:51:38 +07:00
value . We can 't print out something that isn' t there ; try giving x a value !
This is an error that can cause bugs that ' s very easy to make in any
programming language -- thankfully the Rust compiler has caught this for us ! "" "
2019-03-07 03:47:00 +07:00
2020-01-15 03:06:43 +07:00
[ [ exercises ] ]
name = "variables5"
path = "exercises/variables/variables5.rs"
mode = "compile"
hint = "" "
In variables3 we already learned how to make an immutable variable mutable
using a special keyword . Unfortunately this doesn ' t help us much in this exercise
because we want to assign a different typed value to an existing variable . Sometimes
you may also like to reuse existing variable names because you are just converting
values to different types like in this exercise .
Fortunately Rust has a powerful solution to this problem : 'Shadowing' !
2020-08-28 00:51:19 +07:00
You can read more about 'Shadowing' in the book 's section ' Variables and Mutability ' :
2020-04-13 00:35:20 +07:00
https : / / doc . rust-lang . org / book / ch03-01-variables-and-mutability . html #shadowing
2020-01-15 03:06:43 +07:00
Try to solve this exercise afterwards using this technique . "" "
2020-04-14 15:13:20 +07:00
[ [ exercises ] ]
name = "variables6"
path = "exercises/variables/variables6.rs"
mode = "compile"
hint = "" "
2020-08-28 00:51:19 +07:00
We know about variables and mutability , but there is another important type of
variable available ; constants .
Constants are always immutable and they are declared with keyword 'const' rather
2020-06-27 18:58:53 +07:00
than keyword 'let' .
2020-04-14 15:13:20 +07:00
Constants types must also always be annotated .
2020-08-28 00:51:19 +07:00
Read more about constants under 'Differences Between Variables and Constants' in the book 's section ' Variables and Mutability ' :
2020-05-28 14:33:15 +07:00
https : / / doc . rust-lang . org / book / ch03-01-variables-and-mutability . html #differences-between-variables-and-constants
2020-04-14 15:13:20 +07:00
"" "
2019-03-07 03:47:00 +07:00
# FUNCTIONS
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "functions1"
2019-03-07 03:47:00 +07:00
path = "exercises/functions/functions1.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
This main function is calling a function that it expects to exist , but the
function doesn ' t exist . It expects this function to have the name ` call_me ` .
It expects this function to not take any arguments and not return a value .
Sounds a lot like ` main ` , doesn ' t it ? "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "functions2"
2019-03-07 03:47:00 +07:00
path = "exercises/functions/functions2.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
Rust requires that all parts of a function ' s signature have type annotations ,
but ` call_me ` is missing the type annotation of ` num ` . "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "functions3"
2019-03-07 03:47:00 +07:00
path = "exercises/functions/functions3.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
This time , the function * declaration * is okay , but there ' s something wrong
with the place where we ' re calling the function . "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "functions4"
2019-03-07 03:47:00 +07:00
path = "exercises/functions/functions4.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
2019-11-13 06:49:19 +07:00
The error message points to line 14 and says it expects a type after the
2019-11-11 22:51:38 +07:00
` - > ` . This is where the function ' s return type should be-- take a look at
the ` is_even ` function for an example ! "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "functions5"
2019-03-07 03:47:00 +07:00
path = "exercises/functions/functions5.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
This is a really common error that can be fixed by removing one character .
It happens because Rust distinguishes between expressions and statements : expressions return
a value based on its operand , and statements simply return a ( ) type which behaves just like ` void ` in C / C + + language .
We want to return a value of ` i32 ` type from the ` square ` function , but it is returning a ` ( ) ` type . . .
They are not the same . There are two solutions :
1 . Add a ` return ` ahead of ` num * num ; `
2019-11-11 22:56:39 +07:00
2 . remove ` ; ` , make it to be ` num * num ` "" "
2019-03-07 03:47:00 +07:00
2020-12-07 21:37:19 +07:00
# IF
[ [ exercises ] ]
name = "if1"
path = "exercises/if/if1.rs"
mode = "test"
hint = "" "
It ' s possible to do this in one line if you would like !
Some similar examples from other languages :
- In C ( + + ) this would be : ` a > b ? a : b `
- In Python this would be : ` a if a > b else b `
Remember in Rust that :
- the ` if ` condition does not need to be surrounded by parentheses
- ` if ` / ` else ` conditionals are expressions
- Each condition is followed by a ` { } ` block . "" "
[ [ exercises ] ]
name = "if2"
path = "exercises/if/if2.rs"
mode = "test"
hint = "" "
For that first compiler error , it ' s important in Rust that each conditional
block return the same type ! To get the tests passing , you will need a couple
conditions checking different input values . "" "
2019-03-07 03:47:00 +07:00
# TEST 1
[ [ exercises ] ]
2020-05-19 23:47:44 +07:00
name = "quiz1"
path = "exercises/quiz1.rs"
2019-03-07 03:47:00 +07:00
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "No hints this time ;)"
2019-03-07 03:47:00 +07:00
2020-12-07 21:37:19 +07:00
# MOVE SEMANTICS
[ [ exercises ] ]
name = "move_semantics1"
path = "exercises/move_semantics/move_semantics1.rs"
mode = "compile"
hint = "" "
So you ' ve got the "cannot borrow immutable local variable `vec1` as mutable" error on line 13 ,
right ? The fix for this is going to be adding one keyword , and the addition is NOT on line 13
where the error is . "" "
[ [ exercises ] ]
name = "move_semantics2"
path = "exercises/move_semantics/move_semantics2.rs"
mode = "compile"
hint = "" "
So ` vec0 ` is being * moved * into the function ` fill_vec ` when we call it on
line 10 , which means it gets dropped at the end of ` fill_vec ` , which means we
can ' t use ` vec0 ` again on line 13 ( or anywhere else in ` main ` after the
` fill_vec ` call for that matter ) . We could fix this in a few ways , try them
all !
1 . Make another , separate version of the data that ' s in ` vec0 ` and pass that
to ` fill_vec ` instead .
2 . Make ` fill_vec ` borrow its argument instead of taking ownership of it ,
and then copy the data within the function in order to return an owned
` Vec < i32 > `
3 . Make ` fill_vec ` * mutably * borrow its argument ( which will need to be
mutable ) , modify it directly , then not return anything . Then you can get rid
of ` vec1 ` entirely -- note that this will change what gets printed by the
first ` println ! ` "" "
[ [ exercises ] ]
name = "move_semantics3"
path = "exercises/move_semantics/move_semantics3.rs"
mode = "compile"
hint = "" "
The difference between this one and the previous ones is that the first line
of ` fn fill_vec ` that had ` let mut vec = vec ; ` is no longer there . You can ,
instead of adding that line back , add ` mut ` in one place that will change
an existing binding to be a mutable binding instead of an immutable one : ) "" "
[ [ exercises ] ]
name = "move_semantics4"
path = "exercises/move_semantics/move_semantics4.rs"
mode = "compile"
hint = "" "
Stop reading whenever you feel like you have enough direction : ) Or try
doing one step and then fixing the compiler errors that result !
So the end goal is to :
- get rid of the first line in main that creates the new vector
- so then ` vec0 ` doesn 't exist, so we can' t pass it to ` fill_vec `
- we don ' t want to pass anything to ` fill_vec ` , so its signature should
reflect that it does not take any arguments
- since we ' re not creating a new vec in ` main ` anymore , we need to create
a new vec in ` fill_vec ` , similarly to the way we did in ` main ` "" "
2021-05-07 00:47:27 +07:00
[ [ exercises ] ]
name = "move_semantics5"
path = "exercises/move_semantics/move_semantics5.rs"
mode = "compile"
hint = "" "Carefully reason about the range in which each mutable reference is in vogue. Does updating the value of referrent (x) immediately after the mutable reference is taken helps ? Read more about 'Mutable Referenes' in the book's section References and Borrowing': https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references." ""
2019-03-07 03:47:00 +07:00
# PRIMITIVE TYPES
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "primitive_types1"
2019-03-07 03:47:00 +07:00
path = "exercises/primitive_types/primitive_types1.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "No hints this time ;)"
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "primitive_types2"
2019-03-07 03:47:00 +07:00
path = "exercises/primitive_types/primitive_types2.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "No hints this time ;)"
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "primitive_types3"
2019-03-07 03:47:00 +07:00
path = "exercises/primitive_types/primitive_types3.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
There ' s a shorthand to initialize Arrays with a certain size that does not
require you to type in 100 items ( but you certainly can if you want ! ) .
For example , you can do :
let array = [ "Are we there yet?" ; 10 ] ;
Bonus : what are some other things you could have that would return true
for ` a . len ( ) > = 100 ` ? "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "primitive_types4"
2019-03-07 03:47:00 +07:00
path = "exercises/primitive_types/primitive_types4.rs"
2019-08-18 07:14:00 +07:00
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
Take a look at the Understanding Ownership - > Slices - > Other Slices section of the book :
https : / / doc . rust-lang . org / book / ch04-03-slices . html
and use the starting and ending indices of the items in the Array
that you want to end up in the slice .
2019-11-13 17:58:03 +07:00
If you ' re curious why the first argument of ` assert_eq ! ` does not
have an ampersand for a reference since the second argument is a
2019-11-11 22:51:38 +07:00
reference , take a look at the Deref coercions section of the book :
2019-11-11 22:56:39 +07:00
https : / / doc . rust-lang . org / book / ch15-02-deref . html "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "primitive_types5"
2019-03-07 03:47:00 +07:00
path = "exercises/primitive_types/primitive_types5.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
Take a look at the Data Types - > The Tuple Type section of the book :
https : / / doc . rust-lang . org / book / ch03-02-data-types . html #the-tuple-type
Particularly the part about destructuring ( second to last example in the section ) .
You ' ll need to make a pattern to bind ` name ` and ` age ` to the appropriate parts
of the tuple . You can do it ! ! "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "primitive_types6"
2019-03-07 03:47:00 +07:00
path = "exercises/primitive_types/primitive_types6.rs"
2020-10-11 19:00:03 +07:00
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
While you could use a destructuring ` let ` for the tuple here , try
indexing into it instead , as explained in the last example of the
Data Types - > The Tuple Type section of the book :
https : / / doc . rust-lang . org / book / ch03-02-data-types . html #the-tuple-type
Now you have another tool in your toolbox ! "" "
2019-03-07 03:47:00 +07:00
2019-05-25 18:39:58 +07:00
# STRUCTS
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "structs1"
2019-05-25 18:39:58 +07:00
path = "exercises/structs/structs1.rs"
mode = "test"
2020-04-16 21:21:36 +07:00
hint = "" "
2020-11-08 16:31:45 +07:00
Rust has more than one type of struct . Three actually , all variants are used to package related data together .
There are normal ( or classic ) structs . These are named collections of related data stored in fields .
Tuple structs are basically just named tuples .
2021-01-30 23:12:06 +07:00
Finally , Unit structs . These don ' t have any fields and are useful for generics .
2020-04-16 21:21:36 +07:00
2020-11-08 16:31:45 +07:00
In this exercise you need to complete and implement one of each kind .
Read more about structs in The Book : https : / / doc . rust-lang . org / book / ch05-01-defining-structs . html "" "
2019-05-25 18:39:58 +07:00
2019-10-21 19:23:06 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "structs2"
2019-10-21 19:23:06 +07:00
path = "exercises/structs/structs2.rs"
mode = "test"
2020-04-16 21:21:36 +07:00
hint = "" "
2020-08-28 00:51:19 +07:00
Creating instances of structs is easy , all you need to do is assign some values to its fields .
2021-03-12 21:38:28 +07:00
There are however some shortcuts that can be taken when instantiating structs .
2020-04-16 21:21:36 +07:00
Have a look in The Book , to find out more : https : / / doc . rust-lang . org / stable / book / ch05-01-defining-structs . html #creating-instances-from-other-instances-with-struct-update-syntax"""
2019-10-21 19:23:06 +07:00
2020-04-28 01:17:26 +07:00
[ [ exercises ] ]
name = "structs3"
path = "exercises/structs/structs3.rs"
mode = "test"
hint = "" "
The new method needs to panic if the weight is physically impossible : ) , how do we do that in Rust ?
For is_international : What makes a package international ? Seems related to the places it goes through right ?
For calculate_transport_fees : Bigger is more expensive usually , we don ' t have size , but something may fit the bill here : )
Have a look in The Book , to find out more about method implementations : https : / / doc . rust-lang . org / book / ch05-03-method-syntax . html "" "
2019-10-29 10:49:49 +07:00
# ENUMS
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "enums1"
2019-10-29 10:49:49 +07:00
path = "exercises/enums/enums1.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
Hint : The declaration of the enumeration type has not been defined yet . "" "
2019-10-29 10:49:49 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "enums2"
2019-10-29 10:49:49 +07:00
path = "exercises/enums/enums2.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
Hint : you can create enumerations that have different variants with different types
such as no data , anonymous structs , a single string , tuples , . . . etc "" "
2019-10-29 10:49:49 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "enums3"
2019-10-29 10:49:49 +07:00
path = "exercises/enums/enums3.rs"
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "No hints this time ;)"
2019-10-29 10:49:49 +07:00
2019-03-07 03:47:00 +07:00
# MODULES
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "modules1"
2019-03-07 03:47:00 +07:00
path = "exercises/modules/modules1.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
Everything is private in Rust by default-- but there ' s a keyword we can use
to make something public ! The compiler error should point to the thing that
needs to be public . "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "modules2"
2019-03-07 03:47:00 +07:00
path = "exercises/modules/modules2.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
The delicious_snacks module is trying to present an external
interface ( the ` fruit ` and ` veggie ` constants ) that is different than
its internal structure ( the ` fruits ` and ` veggies ` modules and
associated constants ) . It ' s almost there except for one keyword missing for
each constant . "" "
2019-03-07 03:47:00 +07:00
2020-12-13 01:21:23 +07:00
# COLLECTIONS
[ [ exercises ] ]
2021-03-19 00:39:22 +07:00
name = "vec1"
2020-12-13 01:21:23 +07:00
path = "exercises/collections/vec1.rs"
mode = "test"
hint = "" "
In Rust , there are two ways to define a Vector .
1 . One way is to use the ` Vec : : new ( ) ` function to create a new vector
and fill it with the ` push ( ) ` method .
2 . The second way , which is simpler is to use the ` vec ! [ ] ` macro and
define your elements inside the square brackets .
Check this chapter : https : / / doc . rust-lang . org / stable / book / ch08-01-vectors . html
of the Rust book to learn more .
"" "
[ [ exercises ] ]
2021-03-19 00:39:22 +07:00
name = "vec2"
2020-12-13 01:21:23 +07:00
path = "exercises/collections/vec2.rs"
mode = "test"
hint = "" "
Hint 1 : ` i ` is each element from the Vec as they are being iterated .
Can you try multiplying this ?
Hint 2 : Check the suggestion from the compiler error ; )
"" "
[ [ exercises ] ]
2021-03-19 00:39:22 +07:00
name = "hashmap1"
2020-12-13 01:21:23 +07:00
path = "exercises/collections/hashmap1.rs"
mode = "test"
hint = "" "
Hint 1 : Take a look at the return type of the function to figure out
the type for the ` basket ` .
Hint 2 : Number of fruits should be at least 5 . And you have to put
at least three different types of fruits .
"" "
[ [ exercises ] ]
2021-03-19 00:39:22 +07:00
name = "hashmap2"
2020-12-13 01:21:23 +07:00
path = "exercises/collections/hashmap2.rs"
mode = "test"
hint = "" "
Use the ` entry ( ) ` and ` or_insert ( ) ` methods of ` HashMap ` to achieve this .
Learn more at https : / / doc . rust-lang . org / stable / book / ch08-03-hash-maps . html #only-inserting-a-value-if-the-key-has-no-value
"" "
2020-12-07 21:37:19 +07:00
# STRINGS
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2020-12-07 21:37:19 +07:00
name = "strings1"
path = "exercises/strings/strings1.rs"
2019-03-07 03:47:00 +07:00
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
2020-12-07 21:37:19 +07:00
The ` current_favorite_color ` function is currently returning a string slice with the ` ' static `
lifetime . We know this because the data of the string lives in our code itself -- it doesn ' t
come from a file or user input or another program -- so it will live as long as our program
lives . But it is still a string slice . There ' s one way to create a ` String ` by converting a
string slice covered in the Strings chapter of the book , and another way that uses the ` From `
trait . "" "
2019-03-07 03:47:00 +07:00
2020-12-07 21:37:19 +07:00
[ [ exercises ] ]
name = "strings2"
path = "exercises/strings/strings2.rs"
2019-03-07 03:47:00 +07:00
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
2020-12-07 21:37:19 +07:00
Yes , it would be really easy to fix this by just changing the value bound to ` word ` to be a
string slice instead of a ` String ` , wouldn ' t it ? ? There is a way to add one character to line
9 , though , that will coerce the ` String ` into a string slice . "" "
# TEST 2
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2020-12-07 21:37:19 +07:00
name = "quiz2"
path = "exercises/quiz2.rs"
2019-03-07 03:47:00 +07:00
mode = "compile"
2020-12-07 21:37:19 +07:00
hint = "No hints this time ;)"
2019-03-07 03:47:00 +07:00
# ERROR HANDLING
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "errors1"
2019-03-07 03:47:00 +07:00
path = "exercises/error_handling/errors1.rs"
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
` Err ` is one of the variants of ` Result ` , so what the 2 nd test is saying
is that ` generate_nametag_text ` should return a ` Result ` instead of an
` Option ` .
To make this change , you ' ll need to :
- update the return type in the function signature to be a Result < String , String > that
could be the variants ` Ok ( String ) ` and ` Err ( String ) `
- change the body of the function to return ` Ok ( stuff ) ` where it currently
returns ` Some ( stuff ) `
- change the body of the function to return ` Err ( error message ) ` where it
currently returns ` None `
- change the first test to expect ` Ok ( stuff ) ` where it currently expects
` Some ( stuff ) ` . "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "errors2"
2019-03-07 03:47:00 +07:00
path = "exercises/error_handling/errors2.rs"
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
One way to handle this is using a ` match ` statement on
` item_quantity . parse : : < i32 > ( ) ` where the cases are ` Ok ( something ) ` and
` Err ( something ) ` . This pattern is very common in Rust , though , so there ' s
a ` ? ` operator that does pretty much what you would make that match statement
do for you ! Take a look at this section of the Error Handling chapter :
https : / / doc . rust-lang . org / book / ch09-02-recoverable-errors-with-result . html #a-shortcut-for-propagating-errors-the--operator
and give it a try ! "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "errors3"
2019-03-07 03:47:00 +07:00
path = "exercises/error_handling/errors3.rs"
2021-03-13 02:04:29 +07:00
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
If other functions can return a ` Result ` , why shouldn ' t ` main ` ? "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 23:47:45 +07:00
name = "errorsn"
2019-03-07 03:47:00 +07:00
path = "exercises/error_handling/errorsn.rs"
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
First hint : To figure out what type should go where the ? ? ? is , take a look
at the test helper function ` test_with_str ` , since it returns whatever
2020-04-25 15:25:41 +07:00
` read_and_validate ` returns and ` test_with_str ` has its signature fully
2019-11-11 22:51:38 +07:00
specified .
Next hint : There are three places in ` read_and_validate ` that we call a
function that returns a ` Result ` ( that is , the functions might fail ) .
Apply the ` ? ` operator on those calls so that we return immediately from
` read_and_validate ` if those function calls fail .
Another hint : under the hood , the ` ? ` operator calls ` From : : from `
on the error value to convert it to a boxed trait object , a Box < dyn error : : Error > ,
which is polymorphic-- that means that lots of different kinds of errors
can be returned from the same function because all errors act the same
since they all implement the ` error : : Error ` trait .
Check out this section of the book :
https : / / doc . rust-lang . org / book / ch09-02-recoverable-errors-with-result . html #a-shortcut-for-propagating-errors-the--operator
Another another hint : Note that because the ` ? ` operator returns
the * unwrapped * value in the ` Ok ` case , if we want to return a ` Result ` from
` read_and_validate ` for * its * success case , we ' ll have to rewrap a value
that we got from the return value of a ` ? ` ed call in an ` Ok ` -- this will
look like ` Ok ( something ) ` .
Another another another hint : ` Result ` s must be "used" , that is , you ' ll
get a warning if you don ' t handle a ` Result ` that you get in your
function . Read more about that in the ` std : : result ` module docs :
https : / / doc . rust-lang . org / std / result / #results-must-be-used"""
2019-03-07 03:47:00 +07:00
2020-12-07 21:37:19 +07:00
# Generics
[ [ exercises ] ]
name = "generics1"
path = "exercises/generics/generics1.rs"
mode = "compile"
hint = "" "
Vectors in rust make use of generics to create dynamically sized arrays of any type .
You need to tell the compiler what type we are pushing onto this vector . "" "
[ [ exercises ] ]
name = "generics2"
path = "exercises/generics/generics2.rs"
mode = "test"
hint = "" "
Currently we are wrapping only values of type 'u32' .
Maybe we could update the explicit references to this data type somehow ?
If you are still stuck https : / / doc . rust-lang . org / stable / book / ch10-01-syntax . html #in-method-definitions
"" "
[ [ exercises ] ]
name = "generics3"
path = "exercises/generics/generics3.rs"
mode = "test"
hint = "" "
To find the best solution to this challenge you ' re going to need to think back to your
knowledge of traits , specifically Trait Bound Syntax - you may also need this : "use std::fmt::Display;"
This is definitely harder than the last two exercises ! You need to think about not only making the
ReportCard struct generic , but also the correct property - you will need to change the implementation
of the struct slightly too . . . you can do it !
"" "
2019-03-07 03:47:00 +07:00
# OPTIONS / RESULTS
2020-04-05 20:45:07 +07:00
[ [ exercises ] ]
name = "option1"
path = "exercises/option/option1.rs"
mode = "compile"
hint = "" "
2020-05-10 18:21:29 +07:00
Hint 1 : Check out some functions of Option :
2020-04-05 20:45:07 +07:00
is_some
is_none
unwrap
and :
pattern matching
2020-05-10 18:21:29 +07:00
Hint 2 : There are no sensible defaults for the value of an Array ; the values need to be filled before use .
2020-04-05 20:45:07 +07:00
"" "
2020-04-08 01:16:10 +07:00
[ [ exercises ] ]
name = "option2"
path = "exercises/option/option2.rs"
mode = "compile"
hint = "" "
check out :
https : / / doc . rust-lang . org / rust-by-example / flow_control / if_let . html
https : / / doc . rust-lang . org / rust-by-example / flow_control / while_let . html
Remember that Options can be stacked in if let and while let .
For example : Some ( Some ( variable ) ) = variable2
2021-01-03 18:42:39 +07:00
Also see Option : : flatten
2020-04-08 01:16:10 +07:00
"" "
2021-05-08 16:52:27 +07:00
[ [ exercises ] ]
name = "option3"
path = "exercises/option/option3.rs"
mode = "compile"
hint = "" "
The compiler says a partial move happened in the ` match `
statement . How can this be avoided ? The compiler shows the correction
needed . After making the correction as suggested by the compiler , do
read : https : / / doc . rust-lang . org / std / keyword . ref . html "" "
2019-03-07 03:47:00 +07:00
[ [ exercises ] ]
2019-11-11 23:47:45 +07:00
name = "result1"
2019-03-07 03:47:00 +07:00
path = "exercises/error_handling/result1.rs"
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
` PositiveNonzeroInteger : : new ` is always creating a new instance and returning an ` Ok ` result .
It should be doing some checking , returning an ` Err ` result if those checks fail , and only
returning an ` Ok ` result if those checks determine that everything is . . . okay : ) "" "
2019-03-07 03:47:00 +07:00
2020-12-07 21:37:19 +07:00
# TRAITS
2020-02-14 21:25:03 +07:00
[ [ exercises ] ]
2020-12-07 21:37:19 +07:00
name = "traits1"
path = "exercises/traits/traits1.rs"
mode = "test"
2020-02-14 21:25:03 +07:00
hint = "" "
2020-12-07 21:37:19 +07:00
A discussion about Traits in Rust can be found at :
https : / / doc . rust-lang . org / book / ch10-02-traits . html
"" "
2020-02-14 21:25:03 +07:00
[ [ exercises ] ]
2020-12-07 21:37:19 +07:00
name = "traits2"
path = "exercises/traits/traits2.rs"
mode = "test"
2020-02-14 21:25:03 +07:00
hint = "" "
2020-12-07 21:37:19 +07:00
Notice how the trait takes ownership of 'self' , and returns ` Self ' .
Try mutating the incoming string vector .
Vectors provide suitable methods for adding an element at the end . See
the documentation at : https : / / doc . rust-lang . org / std / vec / struct . Vec . html "" "
# TESTS
[ [ exercises ] ]
name = "tests1"
path = "exercises/tests/tests1.rs"
mode = "test"
hint = "" "
You don ' t even need to write any code to test -- you can just test values and run that , even
though you wouldn ' t do that in real life : ) ` assert ! ` is a macro that needs an argument .
Depending on the value of the argument , ` assert ! ` will do nothing ( in which case the test will
pass ) or ` assert ! ` will panic ( in which case the test will fail ) . So try giving different values
to ` assert ! ` and see which ones compile , which ones pass , and which ones fail : ) "" "
[ [ exercises ] ]
name = "tests2"
path = "exercises/tests/tests2.rs"
mode = "test"
hint = "" "
Like the previous exercise , you don ' t need to write any code to get this test to compile and
run . ` assert_eq ! ` is a macro that takes two arguments and compares them . Try giving it two
values that are equal ! Try giving it two arguments that are different ! Try giving it two values
that are of different types ! Try switching which argument comes first and which comes second ! "" "
[ [ exercises ] ]
name = "tests3"
path = "exercises/tests/tests3.rs"
mode = "test"
hint = "" "
You can call a function right where you ' re passing arguments to ` assert ! ` -- so you could do
something like ` assert ! ( having_fun ( ) ) ` . If you want to check that you indeed get false , you
can negate the result of what you ' re doing using ` ! ` , like ` assert ! ( ! having_fun ( ) ) ` . "" "
# TEST 3
[ [ exercises ] ]
name = "quiz3"
path = "exercises/quiz3.rs"
mode = "test"
hint = "No hints this time ;)"
2020-02-14 21:25:03 +07:00
2019-03-13 21:29:02 +07:00
# STANDARD LIBRARY TYPES
2020-05-27 03:46:24 +07:00
[ [ exercises ] ]
name = "box1"
path = "exercises/standard_library_types/box1.rs"
2020-05-27 16:03:59 +07:00
mode = "test"
2020-05-27 03:46:24 +07:00
hint = "" "
Step 1
The compiler ' s message should help : since we cannot store the value of the actual type
when working with recursive types , we need to store a reference ( pointer ) to its value .
2020-05-27 16:03:59 +07:00
We should , therefore , place our ` List ` inside a ` Box ` . More details in the book here :
2020-05-27 03:46:24 +07:00
https : / / doc . rust-lang . org / book / ch15-01-box . html #enabling-recursive-types-with-boxes
Step 2
Creating an empty list should be fairly straightforward ( hint : peek at the assertions ) .
2020-05-27 16:03:59 +07:00
For a non-empty list keep in mind that we want to use our Cons "list builder" .
2020-05-27 03:46:24 +07:00
Although the current list is one of integers ( i32 ) , feel free to change the definition
and try other types !
"" "
2019-03-13 21:29:02 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "arc1"
2019-03-13 21:29:02 +07:00
path = "exercises/standard_library_types/arc1.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
Make ` shared_numbers ` be an ` Arc ` from the numbers vector . Then , in order
to avoid creating a copy of ` numbers ` , you ' ll need to create ` child_numbers `
inside the loop but still in the main thread .
` child_numbers ` should be a clone of the Arc of the numbers instead of a
2021-04-21 19:50:03 +07:00
thread-local copy of the numbers .
This is a simple exercise if you understand the underlying concepts , but if this
is too much of a struggle , consider reading through all of Chapter 16 in the book :
https : / / doc . rust-lang . org / stable / book / ch16-00-concurrency . html
"" "
2019-03-13 21:29:02 +07:00
2020-12-13 01:21:23 +07:00
[ [ exercises ] ]
name = "iterators1"
path = "exercises/standard_library_types/iterators1.rs"
mode = "compile"
hint = "" "
Step 1 :
We need to apply something to the collection ` my_fav_fruits ` before we start to go through
it . What could that be ? Take a look at the struct definition for a vector for inspiration :
https : / / doc . rust-lang . org / std / vec / struct . Vec . html .
Step 2 & step 2.1 :
Very similar to the lines above and below . You ' ve got this !
Step 3 :
An iterator goes through all elements in a collection , but what if we ' ve run out of
2021-03-13 02:04:29 +07:00
elements ? What should we expect here ? If you ' re stuck , take a look at
2020-12-13 01:21:23 +07:00
https : / / doc . rust-lang . org / std / iter / trait . Iterator . html for some ideas .
"" "
2019-07-02 18:21:58 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "iterators2"
2019-07-02 18:21:58 +07:00
path = "exercises/standard_library_types/iterators2.rs"
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
Step 1
2021-02-12 09:24:32 +07:00
The variable ` first ` is a ` char ` . It needs to be capitalized and added to the
remaining characters in ` c ` in order to return the correct ` String ` .
The remaining characters in ` c ` can be viewed as a string slice using the
` as_str ` method .
The documentation for ` char ` contains many useful methods .
2019-11-11 22:51:38 +07:00
https : / / doc . rust-lang . org / std / primitive . char . html
Step 2
2021-02-12 09:24:32 +07:00
Create an iterator from the slice . Transform the iterated values by applying
the ` capitalize_first ` function . Remember to collect the iterator .
2019-11-11 22:51:38 +07:00
Step 3 .
2021-02-12 09:24:32 +07:00
This is surprising similar to the previous solution . Collect is very powerful
and very general . Rust just needs to know the desired type . "" "
2019-07-02 18:21:58 +07:00
2019-03-13 21:29:02 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "iterators3"
2019-06-07 09:10:08 +07:00
path = "exercises/standard_library_types/iterators3.rs"
2019-03-13 21:29:02 +07:00
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
2021-02-13 03:36:53 +07:00
The divide function needs to return the correct error when even division is not
possible .
2019-11-11 22:51:38 +07:00
2021-02-13 03:36:53 +07:00
The division_results variable needs to be collected into a collection type .
The result_with_list function needs to return a single Result where the success
case is a vector of integers and the failure case is a DivisionError .
The list_of_results function needs to return a vector of results . "" "
2019-03-13 21:29:02 +07:00
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "iterators4"
2019-03-13 21:29:02 +07:00
path = "exercises/standard_library_types/iterators4.rs"
mode = "test"
2019-11-11 22:51:38 +07:00
hint = "" "
2020-08-28 00:51:19 +07:00
In an imperative language , you might write a for loop that updates
a mutable variable . Or , you might write code utilizing recursion
2020-04-30 09:11:54 +07:00
and a match clause . In Rust you can take another functional
approach , computing the factorial elegantly with ranges and iterators . "" "
2019-11-11 19:48:09 +07:00
2021-02-11 06:03:29 +07:00
[ [ exercises ] ]
name = "iterators5"
path = "exercises/standard_library_types/iterators5.rs"
mode = "test"
hint = "" "
The documentation for the std : : iter : : Iterator trait contains numerous methods
that would be helpful here .
2021-04-21 05:52:10 +07:00
Return 0 from count_collection_iterator to make the code compile in order to
test count_iterator .
2021-02-11 06:03:29 +07:00
2021-04-21 05:52:10 +07:00
The collection variable in count_collection_iterator is a slice of HashMaps . It
needs to be converted into an iterator in order to use the iterator methods .
2021-02-11 06:03:29 +07:00
2021-04-21 05:52:10 +07:00
The fold method can be useful in the count_collection_iterator function . "" "
2021-02-11 06:03:29 +07:00
2019-11-11 19:48:09 +07:00
# THREADS
[ [ exercises ] ]
2019-11-11 21:46:32 +07:00
name = "threads1"
2019-11-11 19:48:09 +07:00
path = "exercises/threads/threads1.rs"
mode = "compile"
2019-11-11 22:51:38 +07:00
hint = "" "
` Arc ` is an Atomic Reference Counted pointer that allows safe , shared access
to * * immutable * * data . But we want to * change * the number of ` jobs_completed `
so we ' ll need to also use another type that will only allow one thread to
mutate the data at a time . Take a look at this section of the book :
https : / / doc . rust-lang . org / book / ch16-03-shared-state . html #atomic-reference-counting-with-arct
and keep reading if you ' d like more hints : )
Do you now have an ` Arc ` ` Mutex ` ` JobStatus ` at the beginning of main ? Like :
` let status = Arc : : new ( Mutex : : new ( JobStatus { jobs_completed : 0 } ) ) ; `
Similar to the code in the example in the book that happens after the text
that says "We can use Arc<T> to fix this." . If not , give that a try ! If you
do and would like more hints , keep reading ! !
Make sure neither of your threads are holding onto the lock of the mutex
while they are sleeping , since this will prevent the other thread from
being allowed to get the lock . Locks are automatically released when
they go out of scope .
Ok , so , real talk , this was actually tricky for * me * to do too . And
I could see a lot of different problems you might run into , so at this
point I 'm not sure which one you' ve hit : )
Please open an issue if you ' re still running into a problem that
these hints are not helping you with , or if you ' ve looked at the sample
answers and don 't understand why they work and yours doesn' t .
If you ' ve learned from the sample solutions , I encourage you to come
back to this exercise and try it again in a few days to reinforce
what you ' ve learned : ) "" "
2019-12-16 20:34:30 +07:00
2020-12-07 21:37:19 +07:00
# MACROS
[ [ exercises ] ]
name = "macros1"
path = "exercises/macros/macros1.rs"
mode = "compile"
hint = "" "
When you call a macro , you need to add something special compared to a
regular function call . If you 're stuck, take a look at what' s inside
` my_macro ` . "" "
[ [ exercises ] ]
name = "macros2"
path = "exercises/macros/macros2.rs"
mode = "compile"
hint = "" "
Macros don ' t quite play by the same rules as the rest of Rust , in terms of
what ' s available where .
Unlike other things in Rust , the order of "where you define a macro" versus
"where you use it" actually matters . "" "
[ [ exercises ] ]
name = "macros3"
path = "exercises/macros/macros3.rs"
mode = "compile"
hint = "" "
In order to use a macro outside of its module , you need to do something
special to the module to lift the macro out into its parent .
The same trick also works on "extern crate" statements for crates that have
exported macros , if you ' ve seen any of those around . "" "
[ [ exercises ] ]
name = "macros4"
path = "exercises/macros/macros4.rs"
mode = "compile"
hint = "" "
You only need to add a single character to make this compile .
The way macros are written , it wants to see something between each
"macro arm" , so it can separate them . "" "
# TEST 4
[ [ exercises ] ]
name = "quiz4"
path = "exercises/quiz4.rs"
mode = "test"
hint = "No hints this time ;)"
# CLIPPY
[ [ exercises ] ]
name = "clippy1"
path = "exercises/clippy/clippy1.rs"
mode = "clippy"
hint = "" "
Floating point calculations are usually imprecise , so asking if two values are exactly equal is asking for trouble "" "
[ [ exercises ] ]
name = "clippy2"
path = "exercises/clippy/clippy2.rs"
mode = "clippy"
hint = "" "
` for ` loops over Option values are more clearly expressed as an ` if let ` "" "
2019-12-16 20:34:30 +07:00
# TYPE CONVERSIONS
[ [ exercises ] ]
name = "using_as"
path = "exercises/conversions/using_as.rs"
2020-09-08 00:09:27 +07:00
mode = "test"
2019-12-16 20:34:30 +07:00
hint = "" "
Use the ` as ` operator to cast one of the operands in the last line of the
` average ` function into the expected return type . "" "
[ [ exercises ] ]
name = "from_into"
path = "exercises/conversions/from_into.rs"
mode = "test"
hint = "" "
Follow the steps provided right before the ` From ` implementation "" "
[ [ exercises ] ]
name = "try_from_into"
path = "exercises/conversions/try_from_into.rs"
mode = "test"
hint = "" "
2020-06-04 21:31:17 +07:00
Follow the steps provided right before the ` TryFrom ` implementation .
2019-12-16 20:34:30 +07:00
You can also use the example at https : / / doc . rust-lang . org / std / convert / trait . TryFrom . html "" "
[ [ exercises ] ]
name = "as_ref_mut"
path = "exercises/conversions/as_ref_mut.rs"
mode = "test"
hint = "" "
Add AsRef < str > as a trait bound to the functions . "" "
[ [ exercises ] ]
name = "from_str"
path = "exercises/conversions/from_str.rs"
mode = "test"
hint = "" "
2020-05-16 04:02:57 +07:00
The implementation of FromStr should return an Ok with a Person object ,
2021-04-05 06:43:38 +07:00
or an Err with an error if the string is not valid .
2020-06-04 21:31:17 +07:00
This is almost like the ` try_from_into ` exercise . "" "