@@ -515,9 +515,45 @@ let x: int = 5;
515515```
516516
517517If I asked you to read this out loud to the rest of the class, you'd say "` x `
518- is a binding with the type ` int ` and the value ` five ` ." Rust requires you to
519- initialize the binding with a value before you're allowed to use it. If
520- we try...
518+ is a binding with the type ` int ` and the value ` five ` ."
519+
520+ By default, bindings are ** immutable** . This code will not compile:
521+
522+ ``` {ignore}
523+ let x = 5i;
524+ x = 10i;
525+ ```
526+
527+ It will give you this error:
528+
529+ ``` {ignore,notrust}
530+ error: re-assignment of immutable variable `x`
531+ x = 10i;
532+ ^~~~~~~
533+ ```
534+
535+ If you want a binding to be mutable, you can use ` mut ` :
536+
537+ ``` {rust}
538+ let mut x = 5i;
539+ x = 10i;
540+ ```
541+
542+ There is no single reason that bindings are immutable by default, but we can
543+ think about it through one of Rust's primary focuses: safety. If you forget to
544+ say ` mut ` , the compiler will catch it, and let you know that you have mutated
545+ something you may not have cared to mutate. If bindings were mutable by
546+ default, the compiler would not be able to tell you this. If you _ did_ intend
547+ mutation, then the solution is quite easy: add ` mut ` .
548+
549+ There are other good reasons to avoid mutable state when possible, but they're
550+ out of the scope of this guide. In general, you can often avoid explicit
551+ mutation, and so it is preferable in Rust. That said, sometimes, mutation is
552+ what you need, so it's not verboten.
553+
554+ Let's get back to bindings. Rust variable bindings have one more aspect that
555+ differs from other languages: bindings are required to be initialized with a
556+ value before you're allowed to use it. If we try...
521557
522558``` {ignore}
523559let x;
@@ -611,8 +647,301 @@ concept: `if`.
611647
612648## If
613649
650+ Rust's take on ` if ` is not particularly complex, but it's much more like the
651+ ` if ` you'll find in a dynamically typed language than in a more traditional
652+ systems language. So let's talk about it, to make sure you grasp the nuances.
653+
654+ ` if ` is a specific form of a more general concept, the 'branch.' The name comes
655+ from a branch in a tree: a decision point, where depending on a choice,
656+ multiple paths can be taken.
657+
658+ In the case of ` if ` , there is one choice that leads down two paths:
659+
660+ ``` rust
661+ let x = 5i ;
662+
663+ if x == 5i {
664+ println! (" x is five!" );
665+ }
666+ ```
667+
668+ If we changed the value of ` x ` to something else, this line would not print.
669+ More specifically, if the expression after the ` if ` evaluates to ` true ` , then
670+ the block is executed. If it's ` false ` , then it is not.
671+
672+ If you want something to happen in the ` false ` case, use an ` else ` :
673+
674+ ```
675+ let x = 5i;
676+
677+ if x == 5i {
678+ println!("x is five!");
679+ } else {
680+ println!("x is not five :(");
681+ }
682+ ```
683+
684+ This is all pretty standard. However, you can also do this:
685+
686+
687+ ```
688+ let x = 5i;
689+
690+ let y = if x == 5i {
691+ 10i
692+ } else {
693+ 15i
694+ };
695+ ```
696+
697+ Which we can (and probably should) write like this:
698+
699+ ```
700+ let x = 5i;
701+
702+ let y = if x == 5i { 10i } else { 15i };
703+ ```
704+
705+ This reveals two interesting things about Rust: it is an expression-based
706+ language, and semicolons are different than in other 'curly brace and
707+ semicolon'-based languages. These two things are related.
708+
709+ ### Expressions vs. Statements
710+
711+ Rust is primarily an expression based language. There are only two kinds of
712+ statements, and everything else is an expression.
713+
714+ So what's the difference? Expressions return a value, and statements do not.
715+ In many languages, ` if ` is a statement, and therefore, ` let x = if ... ` would
716+ make no sense. But in Rust, ` if ` is an expression, which means that it returns
717+ a value. We can then use this value to initialize the binding.
718+
719+ Speaking of which, bindings are a kind of the first of Rust's two statements.
720+ The proper name is a ** declaration statement** . So far, ` let ` is the only kind
721+ of declaration statement we've seen. Let's talk about that some more.
722+
723+ In some languages, variable bindings can be written as expressions, not just
724+ statements. Like Ruby:
725+
726+ ``` {ruby}
727+ x = y = 5
728+ ```
729+
730+ In Rust, however, using ` let ` to introduce a binding is _ not_ an expression. The
731+ following will produce a compile-time error:
732+
733+ ``` {ignore}
734+ let x = (let y = 5i); // found `let` in ident position
735+ ```
736+
737+ The compiler is telling us here that it was expecting to see the beginning of
738+ an expression, and a ` let ` can only begin a statement, not an expression.
739+
740+ However, re-assigning to a mutable binding is an expression:
741+
742+ ``` {rust}
743+ let mut x = 0i;
744+ let y = x = 5i;
745+ ```
746+
747+ In this case, we have an assignment expression (` x = 5 ` ) whose value is
748+ being used as part of a ` let ` declaration statement (` let y = ... ` ).
749+
750+ The second kind of statement in Rust is the ** expression statement** . Its
751+ purpose is to turn any expression into a statement. In practical terms, Rust's
752+ grammar expects statements to follow other statements. This means that you use
753+ semicolons to separate expressions from each other. This means that Rust
754+ looks a lot like most other languages that require you to use semicolons
755+ at the end of every line, and you will see semicolons at the end of almost
756+ every line of Rust code you see.
757+
758+ What is this exception that makes us say 'almost?' You saw it already, in this
759+ code:
760+
761+ ```
762+ let x = 5i;
763+
764+ let y: int = if x == 5i { 10i } else { 15i };
765+ ```
766+
767+ Note that I've added the type annotation to ` y ` , to specify explicitly that I
768+ want ` y ` to be an integer.
769+
770+ This is not the same as this, which won't compile:
771+
772+ ``` {ignore}
773+ let x = 5i;
774+
775+ let y: int = if x == 5 { 10i; } else { 15i; };
776+ ```
777+
778+ Note the semicolons after the 10 and 15. Rust will give us the following error:
779+
780+ ``` {ignore,notrust}
781+ error: mismatched types: expected `int` but found `()` (expected int but found ())
782+ ```
783+
784+ We expected an integer, but we got ` () ` . ` () ` is pronounced 'unit', and is a
785+ special type in Rust's type system. ` () ` is different than ` null ` in other
786+ languages, because ` () ` is distinct from other types. For example, in C, ` null `
787+ is a valid value for a variable of type ` int ` . In Rust, ` () ` is _ not_ a valid
788+ value for a variable of type ` int ` . It's only a valid value for variables of
789+ the type ` () ` , which aren't very useful. Remember how we said statements don't
790+ return a value? Well, that's the purpose of unit in this case. The semicolon
791+ turns any expression into a statement by throwing away its value and returning
792+ unit instead.
793+
794+ There's one more time in which you won't see a semicolon at the end of a line
795+ of Rust code. For that, we'll need our next concept: functions.
796+
614797## Functions
615798
799+ You've already seen one function so far, the ` main ` function:
800+
801+ ``` {rust}
802+ fn main() {
803+ }
804+ ```
805+
806+ This is the simplest possible function declaration. As we mentioned before,
807+ ` fn ` says 'this is a function,' followed by the name, some parenthesis because
808+ this function takes no arguments, and then some curly braces to indicate the
809+ body. Here's a function named ` foo ` :
810+
811+ ``` {rust}
812+ fn foo() {
813+ }
814+ ```
815+
816+ So, what about taking arguments? Here's a function that prints a number:
817+
818+ ``` {rust}
819+ fn print_number(x: int) {
820+ println!("x is: {}", x);
821+ }
822+ ```
823+
824+ Here's a complete program that uses ` print_number ` :
825+
826+ ``` {rust}
827+ fn main() {
828+ print_number(5);
829+ }
830+
831+ fn print_number(x: int) {
832+ println!("x is: {}", x);
833+ }
834+ ```
835+
836+ As you can see, function arguments work very similar to ` let ` declarations:
837+ you add a type to the argument name, after a colon.
838+
839+ Here's a complete program that adds two numbers together and prints them:
840+
841+ ``` {rust}
842+ fn main() {
843+ print_sum(5, 6);
844+ }
845+
846+ fn print_sum(x: int, y: int) {
847+ println!("sum is: {}", x + y);
848+ }
849+ ```
850+
851+ You separate arguments with a comma, both when you call the function, as well
852+ as when you declare it.
853+
854+ Unlike ` let ` , you _ must_ declare the types of function arguments. This does
855+ not work:
856+
857+ ``` {ignore}
858+ fn print_number(x, y) {
859+ println!("x is: {}", x + y);
860+ }
861+ ```
862+
863+ You get this error:
864+
865+ ``` {ignore,notrust}
866+ hello.rs:5:18: 5:19 error: expected `:` but found `,`
867+ hello.rs:5 fn print_number(x, y) {
868+ ```
869+
870+ This is a deliberate design decision. While full-program inference is possible,
871+ languages which have it, like Haskell, often suggest that documenting your
872+ types explicitly is a best-practice. We agree that forcing functions to declare
873+ types while allowing for inference inside of function bodies is a wonderful
874+ compromise between full inference and no inference.
875+
876+ What about returning a value? Here's a function that adds one to an integer:
877+
878+ ``` {rust}
879+ fn add_one(x: int) -> int {
880+ x + 1
881+ }
882+ ```
883+
884+ Rust functions return exactly one value, and you declare the type after an
885+ 'arrow', which is a dash (` - ` ) followed by a greater-than sign (` > ` ).
886+
887+ You'll note the lack of a semicolon here. If we added it in:
888+
889+ ``` {ignore}
890+ fn add_one(x: int) -> int {
891+ x + 1;
892+ }
893+ ```
894+
895+ We would get an error:
896+
897+ ``` {ignore,notrust}
898+ note: consider removing this semicolon:
899+ x + 1;
900+ ^
901+ error: not all control paths return a value
902+ fn add_one(x: int) -> int {
903+ x + 1;
904+ }
905+ ```
906+
907+ Remember our earlier discussions about semicolons and ` () ` ? Our function claims
908+ to return an ` int ` , but with a semicolon, it would return ` () ` instead. Rust
909+ realizes this probably isn't what we want, and suggests removing the semicolon.
910+
911+ This is very much like our ` if ` statement before: the result of the block
912+ (` {} ` ) is the value of the expression. Other expression-oriented languages,
913+ such as Ruby, work like this, but it's a bit unusual in the systems programming
914+ world. When people first learn about this, they usually assume that it
915+ introduces bugs. But because Rust's type system is so strong, and because unit
916+ is its own unique type, we have never seen an issue where adding or removing a
917+ semicolon in a return position would cause a bug.
918+
919+ But what about early returns? Rust does have a keyword for that, ` return ` :
920+
921+ ``` {rust}
922+ fn foo(x: int) -> int {
923+ if x < 5 { return x; }
924+
925+ x + 1
926+ }
927+ ```
928+
929+ Using a ` return ` as the last line of a function works, but is considered poor
930+ style:
931+
932+ ``` {rust}
933+ fn foo(x: int) -> int {
934+ if x < 5 { return x; }
935+
936+ return x + 1;
937+ }
938+ ```
939+
940+ There are some additional ways to define functions, but they involve features
941+ that we haven't learned about yet, so let's just leave it at that for now.
942+
943+ ## Comments
944+
616945return
617946
618947comments
0 commit comments