Rust is a "curly-brace, block-structured expression language." Rust, at a basic level, looks very similar to C and its family of languages. The curly braces are used the same way, semicolons are used at the end of statements (except in a few cases), and it has many of the same control structures. Once you dive in, you will find that much of the syntax is quite a bit different though. This is the functional side of the language shining through. Throughout all of this, you will find that Rust is still a very young language that is still changing daily. This poses a few problems, such as a lack of tutorials and StackOverflow questions, but the benefits of Rust far outweigh these problems.
Setting up
On most unix systems:
git clone git://github.com/mozilla/rust.git
cd rust
git checkout incoming
./configure
make
sudo make install
Your First Program
Writing your first program is very simple. You simply define a function called main.
You can then compile the code with the following command:rustc HelloWorld.rs
which then creates an executable file named HelloWorld that you can run like normal (./HelloWorld).
Looking at the code, you will see that methods are declared with "fn." After that, it looks a lot like C with the method name followed by a list of arguments and curly braces.
Pointers
Having a strong java and C# background, I was not the best at using pointers. Aside from a few college classes in C++, I have barely used it. This is one of the reasons I like Rust so much - it forces you to manage your memory effectively.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() | |
{ | |
let x = ~0; | |
println(fmt!("%?", *x)); | |
} |
When you declare a variable as usual, let x = 0, it places this memory on the stack. This means when the data gets copied, the entire structure gets copied as well. While this is not a problem for smaller variables, sometimes it is better to create a box on the heap and only hold a pointer to it. This is where the different types of pointers come in.
~
Using ~ will give you an "owned" box. This means that it inherits the lifetime and mutability of its owner. In other words, if you declare a box with ~, then that object can only ever have one owner at a timer. If, for example, I were to do this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() | |
{ | |
let x = ~0; | |
let y = x; | |
println(fmt!("%?", *x)); | |
} |
The compilation would fail with the error message: "error: use of moved value: `x.`" Since x gave its "rights" to its box to y, it can no longer reference that box.
@
What if you want to have two pointers to the same box though? That's where @, the "managed" pointer comes in. If you try writing the same code as before:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() | |
{ | |
let x = @0; | |
let y = x; | |
println(fmt!("%?", *x)); | |
} |
&
When you have a ~ box, but you want to pass it into a method, you can use &, a "borrowed" pointer. The name is pretty self-explanatory. It takes a pointer and makes the box its own for a short while before handing it back.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn main() | |
{ | |
let x = ~0; | |
let y = add(x); | |
println(fmt!("%?", y)); | |
} | |
fn add(input : &int) -> int | |
{ | |
return *input + 1; | |
} |
I added a few more things in that last section of code - namely another method. It is done very similar to C, except that the return type is listed after the list of arguments and preceded by "->"
You have also probably noticed the call to fmt!() in the println() method. This is very similar to a String.format() found in other languages. %s denotes a string, %d denotes a number, and a few other directives. %? is interesting in that it will attempt to display any type, no matter what it is.
Control
Control statements look very similar to C.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn compare(x : int, y : int) -> ~str | |
{ | |
if (x > y) | |
{ | |
return ~"Greater than"; | |
} | |
else if ( x == y) | |
{ | |
return ~"Equal"; | |
} | |
else | |
{ | |
return ~"Less than"; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn compare(x : int, y : int) -> ~str | |
{ | |
if (x > y) | |
{ | |
~"Greater than" | |
} | |
else if ( x == y) | |
{ | |
~"Equal" | |
} | |
else | |
{ | |
~"Less than" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let z = | |
if (x > y) | |
{ | |
~"Greater than" | |
} | |
else if ( x == y) | |
{ | |
~"Equal" | |
} | |
else | |
{ | |
~"Less than" | |
}; |
Pattern Matching
The equivalent to a switch statement in Rust is called "match."
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let string = | |
match someNumber | |
{ | |
0 => "zero", | |
1 | 2 | 4 => "one or two or four", | |
3 | 5..10 => "three or five through ten", | |
_ => "something else" | |
}; |
This is the end of part1 of my Rust tutorial. Part 2 will come soon!