stevedonovan / gentle-intro Goto Github PK
View Code? Open in Web Editor NEWA gentle Rust tutorial
License: MIT License
A gentle Rust tutorial
License: MIT License
I want to collect as many 'pain points' you have encountered learning Rust, so that we can highlight these things in the text, or even add a dedicated chapter. These will often depend on the background of the beginner, so we have to find an elegant way to address different backgrounds without boring/confusing other people. So language-specific items are definitely an idea.
fn how(i: u32) -> &'static str {
match i {
0: 'none',
1: 'one',
_: 'many'
}
}
->
fn how(i: u32) -> &'static str {
match i {
0 => "none",
1 => "one",
_ => "many"
}
}
I'm submitting this before I create a PR just in case I'm misunderstanding what I'm reading, but I believe there's a typo in 1-basics.md:
Which won't produce any input. But change 42 to 40:
should probably read:
Which won't produce any output. But change 42 to 40:
Mind if I submit a PR for this?
EDIT: I also just found this:
how to write an slice type
should probably read:
how to write a slice type
or possibly even:
how to write a slice's type
Any thoughts/preference on that one?
For example, if we just had `.stdout(Stdio::piped())` then the child's standard output is redirected to a pipe. Then `child.stdout` is something you can use to directly
read the output (i.e. implements `Read`). Likewise, you can use the `.stdout(Stdio::piped())`
method so you can write to `child.stdin`.
.stdout(Stdio::piped())
change to .stdin***
And
github source >> https://github.com/chinanf-boy/gentle-intro
web site >> https://chinanf-boy.github.io/gentle-intro
It seems that failure
is the new way to handle errors in Rust, and if I understand correctly it may become the suggested or default Rust error handling method in future. The "Error Handling" chapter should include a section on failure
.
RUST seems now to automatically convert the array to an iterator.
In section 1 at least
x*x
most people write
x * x
and with
n*factorial(n-1)
instead
n * factorial(n - 1)
a minor thing but I figured I'd mention it!
Small spelling mistake.
Very nice, I really like your style of writing! It's a bit more sudden in introducing new things, and mentions a lot of nice details on the side. I only wish you'd add some links to learn more about that :)
For example, here, when you introduce formatting syntax with println!("{:.1} ",x);
, people might wonder where they can lear more about this, so why not add a link to the std::fmt
docs? (This is also one of the most underappreciated parts of the std docs!)
Or, when you introduce Option, Vec, Iterator, etc. and present a few methods โ their API docs have so many other interesting things!
Hi.. well this is not a bug reporting, this is a question and request for assistant.
How you got the you write at .md
a:
To appear as executable code at the book:
What shall I do to write a code like this, I noticed this in many books
about rust, but do not know what they call it, and how they do it :)
Thanks
in
let cosine = x.cos()
The index page says
There will be some uphill but the view will be inspiring; the community is unusually pleasant and happy to help. There is the Rust Users Forum and an active subreddit which is unusually well-moderated. The FAQ is a good resource if you have specific questions.
The original FAQ was moved (bug 291) to https://prev.rust-lang.org/en-US/faq.html. This needs to be fixed.
The first C program I wrote (on an DOS PC) took out the whole computer. Unix systems always behaved better, and only the process died with a segfault. Why is this worse than a Rust (or Go) program panicking? Because the panic happens when the original problem happens, not when the program has become hopelessly confused and eaten all your homework.
This is true, but it's not the root of the issue: the root is that panics don't introduce memory unsafety, nor undefined behavior. This means a panic can't cause a security issue in the same way a segfault can.
mdbook expects to find SUMMARY.md inside ./src
, so how about renaming src/
to code/
and moving content to src/
. I just checked... works well. I see there will ne a need for further small changes. I can submit a PR if this looks like the right idea.
But uncomment let get ...
-> But uncomment let mut set ...
Hi,
Thank you for writing a Rust tutorial!
Can we please get a static ePUB published, with a table of contents? That way, the tutorial will be easier to read offline, such as on ereader devices.
Title pretty much explains it. I was going to do a pull request but wasn't sure how to explain it (I'm a rust newb).
Hi,
Thanks for hosting and writing the gentle intro!
I noticed that https://stevedonovan.github.io/rust-gentle-intro is built with an older version of rustbook. Newer versions improve the clarity of various things like controls and code samples, and you may wish to consider rebuilding to take advantage of these.
Thanks!
Tim.
AddAssign is the name of the trait implementing the += operator,
This is the first time you mention traits, and you don't explain them here.
I may be missing something, but the text says that this snippet from the closures section "Can't be done", but it seems to compile without any trouble (using rustc 1.38.0). Thanks for your work on this guide!
.
fn main() {
let mut s = "world";
// closure does a mutable borrow of s
let mut changer = || s = "world";
changer();
// does an immutable borrow of s
assert_eq!(s, "world");
}
In 1-basics: "The () type is the empty type, nada, void, zilch, nothing. Everything in Rust has a value, but sometimes it's just nothing." The type ()
actually is a type with a single value, ()
. It is usually referred to as the "unit type", since it is inhabited by just the one value. The empty type, the type inhabited by no values, is !
.
This is important, because the unit value is useful in programs:
match v {
Some(v) => println!("{}", v),
None => (),
}
Documentation is now opt in, add a note in Learning Where to Find the Ropes:
rustup component add rust-docs
In 7-shared-and-networking.md, I struggle to understand this:
However, Cell only works with values that can be copied, that is, they implement Copy, like primitive types and structs containing them marked as 'derive(Copy)'.
It seems to say that Cell works with structs so long as its members are Copy, and itself is marked as Copy.
As an aside, perhaps splitting the sentence in 2 would help as well... it feels overlong.
Hello,
first: thank you for the great guide you put together: this gentle intro is very well done and I wish it could be part of the official documentation.
Next, while trying some code from chapter 2, generic functions, I noticed that the generic multiplication does not need the Copy
trait (I am using rust 1.37.0). Maybe you could add a short explanation of why that is not needed anymore (if that is the case).
Thanks a lot for all your great work, that I hope you have time to continue :)
In 1-basics: "languages like Haskell have such powerful type inference that there are hardly any explicit type names". Probably something more like "languages like Haskell have such powerful type inference that almost no explicit types are required"?
The first example did not run until I changed tag_s to tag.
In 7-shared-and-networking.md, code example marked thread2.rs
does not match content of the file with the same name
It runs fine if I remove Arc wrapper. This is 7-shared-and-networking.md
In 1-basics: "There's a lot of cleverness in the language, but it tries not to anything." I think this is not a clever joke, but rather a missing word or phrase?
The file 3-filesystems.md has a few bad code examples (won't compile) right in the beginning:
fn read_all_lines(filename: &str) -> io::Result<()> {
let file = File::open(&filename)?;
let mut lines = Lines::new(file);
while let Some(line) = lines.next() {
let line = line?;
println!("{}", line)?;
}
Ok(())
}
There, println!("{}", line)?;
won't compile because println!
returns ()
and not Result
.
The same happens on the very next code example:
while let Some(Ok(line)) = lines.next() {
println!"{}", line)?;
}
Which even has a parenthesis missing.
I started reading your gentle introduction to Rust, and noticed this line on the first page:
There will be some uphill but the view will be inspiring; the community is unusually pleasant and happy to help. There is the Rust Users Forum and an active subreddit which is unusually well-moderated.
I have to say that this is completely false, and many people know it. It's not just me. Many people have complaints about the toxic and divisive Rust community, the biased moderation, and the censorship. It is especially bad on the subreddit. There are threads where posts have been mass deleted because they went against the narrative, questioning decisions that had been made (such as when Ashley Williams was added to the team). These were perfectly innocent posts, not being hostile or attacking anyone, merely stating facts and questioning the decisions, and they just got deleted.
I myself have been subjected to attacks by the Rust community, because of my political beliefs. One of the moderators on the subreddit actually PMed me and called me a Nazi because I happened to support an elected president. Other members on the subreddit went through my post history and called me a Nazi or a bigot just because of my political opinion, when I was perfectly polite to them and only wanted help learning the Rust programming language. They had the nerve to call me bigoted, when they were the ones showing bigotry. It's just insane.
I doubt this will get much attention, as you have your opinion and consider the Rust community to be good. But to me this is just totally false and is ignoring a very real problem, and just brushing it under the carpet out of sight. Ignoring it and making false promises isn't the way to solve this. Dealing with it and improving it is. In my opinion, people new to Rust should be warned that the community is not welcoming, so that they know what to expect and will not get an unpleasant surprise later on.
gentle-intro/src/6-error-handling.md
Line 19 in 11650e1
Trait objects without an explicit 'dyn' are deprecated
Original:
since it contains a allocated
pointer to the data, and always has a fixed size.
New:
since it contains an allocated
pointer to the data, and always has a fixed size.
The official term is just "slice"; that is, these slices can be for vectors as well as arrays.
First I'd like to say that chapter 8 was excellent, from the perspective of this C++/C# developer, at least. I've just started learning Rust, so I've yet to read the other chapters. Mostly slacking off from the Rust book...
However, I was confused by the last example - it looks like traits can have functions implementations in them (the show
method on the Window
trait).
This surprised me for 2 reasons:
show
automatically?You should perhaps clarify :
First example at http://stevedonovan.github.io/rust-gentle-intro/1-basics.html#learning-where-to-find-the-ropes
#![allow(unused_variables)]
fn main() {
let pi = 3.1416;
let x = pi/2.0;
let cosine = x.cos();
}
output when run in browser is
Compiling playground v0.0.1 (file:///playground)
error[E0599]: no method named `cos` found for type `{float}` in the current scope
--> src/main.rs:6:16
|
6 | let cosine = x.cos();
| ^^^
error: aborting due to previous error
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
I know this is probably something trivial. But I'm a total n00b, and that's why I'm reading this tutorial!
In 1. Basics ~ Matching inclusive range should be written ..=
:
warning: `...` range patterns are deprecated
--> src/main.rs:5:10
|
5 | 0...3 => "small",
| ^^^ help: use `..=` for an inclusive range
|
= note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
Had an error trying:
let last = slice.get(5).unwrap_or(-1);
This worked:
let last = slice.get(5).unwrap_or(&-1):
Full code:
fn main() {
let ints = [1, 2, 3, 4, 5];
let slice = &ints;
let first = slice.get(0);
let last = slice.get(5);
println!("first: {}", first.unwrap_or(&-1));
println!("last: {}", last.unwrap_or(&-1));
}
Thanks for the tutorial.
In section Optional Values the provided example does not compile for me with rustc 1.16.0.
fn main() {
let ints = [1, 2, 3, 4, 5];
let slice = &ints;
let maybe_last = slice.get(5);
let last = if maybe_last.is_some() {
maybe_last.unwrap()
} else {
-1
};
}
The error message is
error[E0308]: if and else have incompatible types
.
If I change the else-clause to
} else {
&-1
};
the error message is error: borrowed value does not live long enough
.
"It's a good example of how extremely flexible convert
is." Probably meant "collect
" here.
Thank you for this project. Has helped me a ton!
2-structs-enums-lifetimes.md
let mut answer = 42;
let set = |v| answer = v;
//let get = || answer;
set(58);
assert_eq!(answer, 58);
Won't compile. Compiler yells set
must be mutable, then it complains about the assertion because answer
is currently mutably borrowed by the closure.
let mut answer = 42;
{
let mut set = |v| answer = v;
//let get = || answer;
set(58);
}
assert_eq!(answer, 58);
Using the extra scope might throw beginners off a little... But at least they'll know there is more to closures (lifetimes and scopes).
I already tried to summarize it at rust-lang/book#276 (comment) for the second-edition book.
But the very short version of it is:
And the reason "immutable variable" is confusing is because all variables in some languages are mutable by default (i.e. without const
or final
), not because "variable" implies mutability.
(You may already know all of this, but I wanted to make sure we're not promoting "it is so because we say so" explanations, when the terms we use are consistent with other disciplines, e.g. mathematics)
I would like to thank you for great tutorials, in FileSystem section, I see this example
use std::fs::File;
use std::io;
use std::io::prelude::*;
fn read_all_lines(filename: &str) -> io::Result<()> {
let file = File::open(&filename)?;
let reader = io::BufReader::new(file);
for line in reader.lines() {
let line = line?;
println!("{}", line);
}
Ok(())
}
this line let file = File::open(&filename)?;
, what is meaning of &
before filename? as it still compile if I remove it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.