Intpocalypse, book edition.
Fix all usage of int/uint/i/u in the book.
This commit is contained in:
parent
078bd498b9
commit
899ffcf62a
@ -116,11 +116,11 @@ pub fn compress(src: &[u8]) -> Vec<u8> {
|
||||
let psrc = src.as_ptr();
|
||||
|
||||
let mut dstlen = snappy_max_compressed_length(srclen);
|
||||
let mut dst = Vec::with_capacity(dstlen as uint);
|
||||
let mut dst = Vec::with_capacity(dstlen as usize);
|
||||
let pdst = dst.as_mut_ptr();
|
||||
|
||||
snappy_compress(psrc, srclen, pdst, &mut dstlen);
|
||||
dst.set_len(dstlen as uint);
|
||||
dst.set_len(dstlen as usize);
|
||||
dst
|
||||
}
|
||||
}
|
||||
@ -148,11 +148,11 @@ pub fn uncompress(src: &[u8]) -> Option<Vec<u8>> {
|
||||
let mut dstlen: size_t = 0;
|
||||
snappy_uncompressed_length(psrc, srclen, &mut dstlen);
|
||||
|
||||
let mut dst = Vec::with_capacity(dstlen as uint);
|
||||
let mut dst = Vec::with_capacity(dstlen as usize);
|
||||
let pdst = dst.as_mut_ptr();
|
||||
|
||||
if snappy_uncompress(psrc, srclen, pdst, &mut dstlen) == 0 {
|
||||
dst.set_len(dstlen as uint);
|
||||
dst.set_len(dstlen as usize);
|
||||
Some(dst)
|
||||
} else {
|
||||
None // SNAPPY_INVALID_INPUT
|
||||
|
@ -5,7 +5,7 @@ multiple types of arguments. For example, remember our `OptionalInt` type?
|
||||
|
||||
```{rust}
|
||||
enum OptionalInt {
|
||||
Value(int),
|
||||
Value(i32),
|
||||
Missing,
|
||||
}
|
||||
```
|
||||
@ -40,26 +40,26 @@ we substitute that type for the same type used in the generic. Here's an
|
||||
example of using `Option<T>`, with some extra type annotations:
|
||||
|
||||
```{rust}
|
||||
let x: Option<int> = Some(5i);
|
||||
let x: Option<i32> = Some(5);
|
||||
```
|
||||
|
||||
In the type declaration, we say `Option<int>`. Note how similar this looks to
|
||||
`Option<T>`. So, in this particular `Option`, `T` has the value of `int`. On
|
||||
the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5i`.
|
||||
Since that's an `int`, the two sides match, and Rust is happy. If they didn't
|
||||
In the type declaration, we say `Option<i32>`. Note how similar this looks to
|
||||
`Option<T>`. So, in this particular `Option`, `T` has the value of `i32`. On
|
||||
the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5`.
|
||||
Since that's an `i32`, the two sides match, and Rust is happy. If they didn't
|
||||
match, we'd get an error:
|
||||
|
||||
```{rust,ignore}
|
||||
let x: Option<f64> = Some(5i);
|
||||
// error: mismatched types: expected `core::option::Option<f64>`
|
||||
// but found `core::option::Option<int>` (expected f64 but found int)
|
||||
let x: Option<f64> = Some(5);
|
||||
// error: mismatched types: expected `core::option::Option<f64>`,
|
||||
// found `core::option::Option<_>` (expected f64 but found integral variable)
|
||||
```
|
||||
|
||||
That doesn't mean we can't make `Option<T>`s that hold an `f64`! They just have to
|
||||
match up:
|
||||
|
||||
```{rust}
|
||||
let x: Option<int> = Some(5i);
|
||||
let x: Option<i32> = Some(5);
|
||||
let y: Option<f64> = Some(5.0f64);
|
||||
```
|
||||
|
||||
|
@ -5,7 +5,7 @@ Let's talk about loops.
|
||||
Remember Rust's `for` loop? Here's an example:
|
||||
|
||||
```{rust}
|
||||
for x in range(0i, 10i) {
|
||||
for x in range(0, 10) {
|
||||
println!("{}", x);
|
||||
}
|
||||
```
|
||||
@ -17,7 +17,7 @@ call the `.next()` method on repeatedly, and it gives us a sequence of things.
|
||||
Like this:
|
||||
|
||||
```{rust}
|
||||
let mut range = range(0i, 10i);
|
||||
let mut range = range(0, 10);
|
||||
|
||||
loop {
|
||||
match range.next() {
|
||||
@ -32,8 +32,8 @@ loop {
|
||||
We make a mutable binding to the return value of `range`, which is our iterator.
|
||||
We then `loop`, with an inner `match`. This `match` is used on the result of
|
||||
`range.next()`, which gives us a reference to the next value of the iterator.
|
||||
`next` returns an `Option<int>`, in this case, which will be `Some(int)` when
|
||||
we have a value and `None` once we run out. If we get `Some(int)`, we print it
|
||||
`next` returns an `Option<i32>`, in this case, which will be `Some(i32)` when
|
||||
we have a value and `None` once we run out. If we get `Some(i32)`, we print it
|
||||
out, and if we get `None`, we `break` out of the loop.
|
||||
|
||||
This code sample is basically the same as our `for` loop version. The `for`
|
||||
@ -50,9 +50,9 @@ primitive. For example, if you needed to iterate over the contents of
|
||||
a vector, you may be tempted to write this:
|
||||
|
||||
```{rust}
|
||||
let nums = vec![1i, 2i, 3i];
|
||||
let nums = vec![1, 2, 3];
|
||||
|
||||
for i in range(0u, nums.len()) {
|
||||
for i in range(0, nums.len()) {
|
||||
println!("{}", nums[i]);
|
||||
}
|
||||
```
|
||||
@ -62,7 +62,7 @@ vectors returns an iterator which iterates through a reference to each element
|
||||
of the vector in turn. So write this:
|
||||
|
||||
```{rust}
|
||||
let nums = vec![1i, 2i, 3i];
|
||||
let nums = vec![1, 2, 3];
|
||||
|
||||
for num in nums.iter() {
|
||||
println!("{}", num);
|
||||
@ -79,12 +79,12 @@ very common with iterators: we can ignore unnecessary bounds checks, but still
|
||||
know that we're safe.
|
||||
|
||||
There's another detail here that's not 100% clear because of how `println!`
|
||||
works. `num` is actually of type `&int`. That is, it's a reference to an `int`,
|
||||
not an `int` itself. `println!` handles the dereferencing for us, so we don't
|
||||
works. `num` is actually of type `&i32`. That is, it's a reference to an `i32`,
|
||||
not an `i32` itself. `println!` handles the dereferencing for us, so we don't
|
||||
see it. This code works fine too:
|
||||
|
||||
```{rust}
|
||||
let nums = vec![1i, 2i, 3i];
|
||||
let nums = vec![1, 2, 3];
|
||||
|
||||
for num in nums.iter() {
|
||||
println!("{}", *num);
|
||||
@ -118,7 +118,7 @@ The most common consumer is `collect()`. This code doesn't quite compile,
|
||||
but it shows the intention:
|
||||
|
||||
```{rust,ignore}
|
||||
let one_to_one_hundred = range(1i, 101i).collect();
|
||||
let one_to_one_hundred = range(1, 101).collect();
|
||||
```
|
||||
|
||||
As you can see, we call `collect()` on our iterator. `collect()` takes
|
||||
@ -128,7 +128,7 @@ type of things you want to collect, and so you need to let it know.
|
||||
Here's the version that does compile:
|
||||
|
||||
```{rust}
|
||||
let one_to_one_hundred = range(1i, 101i).collect::<Vec<int>>();
|
||||
let one_to_one_hundred = range(1, 101).collect::<Vec<i32>>();
|
||||
```
|
||||
|
||||
If you remember, the `::<>` syntax allows us to give a type hint,
|
||||
@ -138,7 +138,7 @@ and so we tell it that we want a vector of integers.
|
||||
is one:
|
||||
|
||||
```{rust}
|
||||
let greater_than_forty_two = range(0i, 100i)
|
||||
let greater_than_forty_two = range(0, 100)
|
||||
.find(|x| *x > 42);
|
||||
|
||||
match greater_than_forty_two {
|
||||
@ -155,8 +155,8 @@ element, `find` returns an `Option` rather than the element itself.
|
||||
Another important consumer is `fold`. Here's what it looks like:
|
||||
|
||||
```{rust}
|
||||
let sum = range(1i, 4i)
|
||||
.fold(0i, |sum, x| sum + x);
|
||||
let sum = range(1, 4)
|
||||
.fold(0, |sum, x| sum + x);
|
||||
```
|
||||
|
||||
`fold()` is a consumer that looks like this:
|
||||
@ -172,24 +172,24 @@ in this iterator:
|
||||
|
||||
| base | accumulator | element | closure result |
|
||||
|------|-------------|---------|----------------|
|
||||
| 0i | 0i | 1i | 1i |
|
||||
| 0i | 1i | 2i | 3i |
|
||||
| 0i | 3i | 3i | 6i |
|
||||
| 0 | 0 | 1 | 1 |
|
||||
| 0 | 1 | 2 | 3 |
|
||||
| 0 | 3 | 3 | 6 |
|
||||
|
||||
We called `fold()` with these arguments:
|
||||
|
||||
```{rust}
|
||||
# range(1i, 4i)
|
||||
.fold(0i, |sum, x| sum + x);
|
||||
# range(1, 4)
|
||||
.fold(0, |sum, x| sum + x);
|
||||
```
|
||||
|
||||
So, `0i` is our base, `sum` is our accumulator, and `x` is our element. On the
|
||||
first iteration, we set `sum` to `0i`, and `x` is the first element of `nums`,
|
||||
`1i`. We then add `sum` and `x`, which gives us `0i + 1i = 1i`. On the second
|
||||
So, `0` is our base, `sum` is our accumulator, and `x` is our element. On the
|
||||
first iteration, we set `sum` to `0`, and `x` is the first element of `nums`,
|
||||
`1`. We then add `sum` and `x`, which gives us `0 + 1 = 1`. On the second
|
||||
iteration, that value becomes our accumulator, `sum`, and the element is
|
||||
the second element of the array, `2i`. `1i + 2i = 3i`, and so that becomes
|
||||
the second element of the array, `2`. `1 + 2 = 3`, and so that becomes
|
||||
the value of the accumulator for the last iteration. On that iteration,
|
||||
`x` is the last element, `3i`, and `3i + 3i = 6i`, which is our final
|
||||
`x` is the last element, `3`, and `3 + 3 = 6`, which is our final
|
||||
result for our sum. `1 + 2 + 3 = 6`, and that's the result we got.
|
||||
|
||||
Whew. `fold` can be a bit strange the first few times you see it, but once it
|
||||
@ -210,14 +210,14 @@ This code, for example, does not actually generate the numbers
|
||||
`1-100`, and just creates a value that represents the sequence:
|
||||
|
||||
```{rust}
|
||||
let nums = range(1i, 100i);
|
||||
let nums = range(1, 100);
|
||||
```
|
||||
|
||||
Since we didn't do anything with the range, it didn't generate the sequence.
|
||||
Let's add the consumer:
|
||||
|
||||
```{rust}
|
||||
let nums = range(1i, 100i).collect::<Vec<int>>();
|
||||
let nums = range(1, 100).collect::<Vec<i32>>();
|
||||
```
|
||||
|
||||
Now, `collect()` will require that `range()` give it some numbers, and so
|
||||
@ -228,7 +228,7 @@ which you've used before. `iter()` can turn a vector into a simple iterator
|
||||
that gives you each element in turn:
|
||||
|
||||
```{rust}
|
||||
let nums = [1i, 2i, 3i];
|
||||
let nums = [1, 2, 3];
|
||||
|
||||
for num in nums.iter() {
|
||||
println!("{}", num);
|
||||
@ -239,12 +239,12 @@ These two basic iterators should serve you well. There are some more
|
||||
advanced iterators, including ones that are infinite. Like `count`:
|
||||
|
||||
```{rust}
|
||||
std::iter::count(1i, 5i);
|
||||
std::iter::count(1, 5);
|
||||
```
|
||||
|
||||
This iterator counts up from one, adding five each time. It will give
|
||||
you a new integer every time, forever (well, technically, until it reaches the
|
||||
maximum number representable by an `int`). But since iterators are lazy,
|
||||
maximum number representable by an `i32`). But since iterators are lazy,
|
||||
that's okay! You probably don't want to use `collect()` on it, though...
|
||||
|
||||
That's enough about iterators. Iterator adapters are the last concept
|
||||
@ -256,7 +256,7 @@ we need to talk about with regards to iterators. Let's get to it!
|
||||
a new iterator. The simplest one is called `map`:
|
||||
|
||||
```{rust,ignore}
|
||||
range(1i, 100i).map(|x| x + 1i);
|
||||
range(1, 100).map(|x| x + 1);
|
||||
```
|
||||
|
||||
`map` is called upon another iterator, and produces a new iterator where each
|
||||
@ -267,7 +267,7 @@ compile the example, you'll get a warning:
|
||||
```{notrust,ignore}
|
||||
warning: unused result which must be used: iterator adaptors are lazy and
|
||||
do nothing unless consumed, #[warn(unused_must_use)] on by default
|
||||
range(1i, 100i).map(|x| x + 1i);
|
||||
range(1, 100).map(|x| x + 1);
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
```
|
||||
|
||||
@ -275,7 +275,7 @@ Laziness strikes again! That closure will never execute. This example
|
||||
doesn't print any numbers:
|
||||
|
||||
```{rust,ignore}
|
||||
range(1i, 100i).map(|x| println!("{}", x));
|
||||
range(1, 100).map(|x| println!("{}", x));
|
||||
```
|
||||
|
||||
If you are trying to execute a closure on an iterator for its side effects,
|
||||
@ -287,7 +287,7 @@ has no side effect on the original iterator. Let's try it out with our infinite
|
||||
iterator from before, `count()`:
|
||||
|
||||
```{rust}
|
||||
for i in std::iter::count(1i, 5i).take(5) {
|
||||
for i in std::iter::count(1, 5).take(5) {
|
||||
println!("{}", i);
|
||||
}
|
||||
```
|
||||
@ -307,7 +307,7 @@ returns `true` or `false`. The new iterator `filter()` produces
|
||||
only the elements that that closure returns `true` for:
|
||||
|
||||
```{rust}
|
||||
for i in range(1i, 100i).filter(|&x| x % 2 == 0) {
|
||||
for i in range(1, 100).filter(|&x| x % 2 == 0) {
|
||||
println!("{}", i);
|
||||
}
|
||||
```
|
||||
@ -322,11 +322,11 @@ You can chain all three things together: start with an iterator, adapt it
|
||||
a few times, and then consume the result. Check it out:
|
||||
|
||||
```{rust}
|
||||
range(1i, 1000i)
|
||||
range(1, 1000)
|
||||
.filter(|&x| x % 2 == 0)
|
||||
.filter(|&x| x % 3 == 0)
|
||||
.take(5)
|
||||
.collect::<Vec<int>>();
|
||||
.collect::<Vec<i32>>();
|
||||
```
|
||||
|
||||
This will give you a vector containing `6`, `12`, `18`, `24`, and `30`.
|
||||
|
@ -54,7 +54,7 @@ The other kind of looping construct in Rust is the `while` loop. It looks like
|
||||
this:
|
||||
|
||||
```{rust}
|
||||
let mut x = 5u32; // mut x: u32
|
||||
let mut x = 5; // mut x: u32
|
||||
let mut done = false; // mut done: bool
|
||||
|
||||
while !done {
|
||||
@ -91,7 +91,7 @@ can do with safety and code generation, so you should always prefer
|
||||
Let's take a look at that `while` loop we had earlier:
|
||||
|
||||
```{rust}
|
||||
let mut x = 5u32;
|
||||
let mut x = 5;
|
||||
let mut done = false;
|
||||
|
||||
while !done {
|
||||
@ -108,7 +108,7 @@ modifying iteration: `break` and `continue`.
|
||||
In this case, we can write the loop in a better way with `break`:
|
||||
|
||||
```{rust}
|
||||
let mut x = 5u32;
|
||||
let mut x = 5;
|
||||
|
||||
loop {
|
||||
x += x - 3;
|
||||
|
@ -11,8 +11,8 @@ which both pattern-match on their input and both return early in one case,
|
||||
doing nothing otherwise:
|
||||
|
||||
~~~~
|
||||
# enum T { SpecialA(uint), SpecialB(uint) }
|
||||
# fn f() -> uint {
|
||||
# enum T { SpecialA(u32), SpecialB(u32) }
|
||||
# fn f() -> u32 {
|
||||
# let input_1 = T::SpecialA(0);
|
||||
# let input_2 = T::SpecialA(0);
|
||||
match input_1 {
|
||||
@ -24,7 +24,7 @@ match input_2 {
|
||||
T::SpecialB(x) => { return x; }
|
||||
_ => {}
|
||||
}
|
||||
# return 0u;
|
||||
# return 0;
|
||||
# }
|
||||
~~~~
|
||||
|
||||
@ -37,8 +37,8 @@ lightweight custom syntax extensions, themselves defined using the
|
||||
the pattern in the above code:
|
||||
|
||||
~~~~
|
||||
# enum T { SpecialA(uint), SpecialB(uint) }
|
||||
# fn f() -> uint {
|
||||
# enum T { SpecialA(u32), SpecialB(u32) }
|
||||
# fn f() -> u32 {
|
||||
# let input_1 = T::SpecialA(0);
|
||||
# let input_2 = T::SpecialA(0);
|
||||
macro_rules! early_return {
|
||||
@ -165,8 +165,8 @@ separator token (a comma-separated list could be written `$(...),*`), and `+`
|
||||
instead of `*` to mean "at least one".
|
||||
|
||||
~~~~
|
||||
# enum T { SpecialA(uint),SpecialB(uint),SpecialC(uint),SpecialD(uint)}
|
||||
# fn f() -> uint {
|
||||
# enum T { SpecialA(u32), SpecialB(u32), SpecialC(u32), SpecialD(u32) }
|
||||
# fn f() -> u32 {
|
||||
# let input_1 = T::SpecialA(0);
|
||||
# let input_2 = T::SpecialA(0);
|
||||
macro_rules! early_return {
|
||||
@ -226,10 +226,10 @@ solves the problem.
|
||||
Now consider code like the following:
|
||||
|
||||
~~~~
|
||||
# enum T1 { Good1(T2, uint), Bad1}
|
||||
# enum T1 { Good1(T2, u32), Bad1}
|
||||
# struct T2 { body: T3 }
|
||||
# enum T3 { Good2(uint), Bad2}
|
||||
# fn f(x: T1) -> uint {
|
||||
# enum T3 { Good2(u32), Bad2}
|
||||
# fn f(x: T1) -> u32 {
|
||||
match x {
|
||||
T1::Good1(g1, val) => {
|
||||
match g1.body {
|
||||
@ -273,10 +273,10 @@ macro_rules! biased_match {
|
||||
)
|
||||
}
|
||||
|
||||
# enum T1 { Good1(T2, uint), Bad1}
|
||||
# enum T1 { Good1(T2, u32), Bad1}
|
||||
# struct T2 { body: T3 }
|
||||
# enum T3 { Good2(uint), Bad2}
|
||||
# fn f(x: T1) -> uint {
|
||||
# enum T3 { Good2(u32), Bad2}
|
||||
# fn f(x: T1) -> u32 {
|
||||
biased_match!((x) -> (T1::Good1(g1, val)) else { return 0 };
|
||||
binds g1, val );
|
||||
biased_match!((g1.body) -> (T3::Good2(result) )
|
||||
@ -383,10 +383,10 @@ macro_rules! biased_match {
|
||||
}
|
||||
|
||||
|
||||
# enum T1 { Good1(T2, uint), Bad1}
|
||||
# enum T1 { Good1(T2, u32), Bad1}
|
||||
# struct T2 { body: T3 }
|
||||
# enum T3 { Good2(uint), Bad2}
|
||||
# fn f(x: T1) -> uint {
|
||||
# enum T3 { Good2(u32), Bad2}
|
||||
# fn f(x: T1) -> u32 {
|
||||
biased_match!(
|
||||
(x) -> (T1::Good1(g1, val)) else { return 0 };
|
||||
(g1.body) -> (T3::Good2(result) ) else { panic!("Didn't get Good2") };
|
||||
@ -528,7 +528,7 @@ A further difficulty occurs when a macro is used in multiple crates. Say that
|
||||
`mylib` defines
|
||||
|
||||
```rust
|
||||
pub fn increment(x: uint) -> uint {
|
||||
pub fn increment(x: u32) -> u32 {
|
||||
x + 1
|
||||
}
|
||||
|
||||
|
@ -418,7 +418,7 @@ struct Wheel {
|
||||
fn main() {
|
||||
let car = Car { name: "DeLorean".to_string() };
|
||||
|
||||
for _ in range(0u, 4) {
|
||||
for _ in range(0, 4) {
|
||||
Wheel { size: 360, owner: car };
|
||||
}
|
||||
}
|
||||
@ -456,7 +456,7 @@ fn main() {
|
||||
|
||||
let car_owner = Rc::new(car);
|
||||
|
||||
for _ in range(0u, 4) {
|
||||
for _ in range(0, 4) {
|
||||
Wheel { size: 360, owner: car_owner.clone() };
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ A quick refresher: you can match against literals directly, and `_` acts as an
|
||||
*any* case:
|
||||
|
||||
```{rust}
|
||||
let x = 1i;
|
||||
let x = 1;
|
||||
|
||||
match x {
|
||||
1 => println!("one"),
|
||||
@ -21,7 +21,7 @@ match x {
|
||||
You can match multiple patterns with `|`:
|
||||
|
||||
```{rust}
|
||||
let x = 1i;
|
||||
let x = 1;
|
||||
|
||||
match x {
|
||||
1 | 2 => println!("one or two"),
|
||||
@ -33,7 +33,7 @@ match x {
|
||||
You can match a range of values with `...`:
|
||||
|
||||
```{rust}
|
||||
let x = 1i;
|
||||
let x = 1;
|
||||
|
||||
match x {
|
||||
1 ... 5 => println!("one through five"),
|
||||
@ -47,7 +47,7 @@ If you're matching multiple things, via a `|` or a `...`, you can bind
|
||||
the value to a name with `@`:
|
||||
|
||||
```{rust}
|
||||
let x = 1i;
|
||||
let x = 1;
|
||||
|
||||
match x {
|
||||
e @ 1 ... 5 => println!("got a range element {}", e),
|
||||
@ -60,11 +60,11 @@ ignore the value and type in the variant:
|
||||
|
||||
```{rust}
|
||||
enum OptionalInt {
|
||||
Value(int),
|
||||
Value(i32),
|
||||
Missing,
|
||||
}
|
||||
|
||||
let x = OptionalInt::Value(5i);
|
||||
let x = OptionalInt::Value(5);
|
||||
|
||||
match x {
|
||||
OptionalInt::Value(..) => println!("Got an int!"),
|
||||
@ -76,11 +76,11 @@ You can introduce *match guards* with `if`:
|
||||
|
||||
```{rust}
|
||||
enum OptionalInt {
|
||||
Value(int),
|
||||
Value(i32),
|
||||
Missing,
|
||||
}
|
||||
|
||||
let x = OptionalInt::Value(5i);
|
||||
let x = OptionalInt::Value(5);
|
||||
|
||||
match x {
|
||||
OptionalInt::Value(i) if i > 5 => println!("Got an int bigger than five!"),
|
||||
@ -93,33 +93,33 @@ If you're matching on a pointer, you can use the same syntax as you declared it
|
||||
with. First, `&`:
|
||||
|
||||
```{rust}
|
||||
let x = &5i;
|
||||
let x = &5;
|
||||
|
||||
match x {
|
||||
&val => println!("Got a value: {}", val),
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `val` inside the `match` has type `int`. In other words, the left-hand
|
||||
side of the pattern destructures the value. If we have `&5i`, then in `&val`, `val`
|
||||
would be `5i`.
|
||||
Here, the `val` inside the `match` has type `i32`. In other words, the left-hand
|
||||
side of the pattern destructures the value. If we have `&5`, then in `&val`, `val`
|
||||
would be `5`.
|
||||
|
||||
If you want to get a reference, use the `ref` keyword:
|
||||
|
||||
```{rust}
|
||||
let x = 5i;
|
||||
let x = 5;
|
||||
|
||||
match x {
|
||||
ref r => println!("Got a reference to {}", r),
|
||||
}
|
||||
```
|
||||
|
||||
Here, the `r` inside the `match` has the type `&int`. In other words, the `ref`
|
||||
Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref`
|
||||
keyword _creates_ a reference, for use in the pattern. If you need a mutable
|
||||
reference, `ref mut` will work in the same way:
|
||||
|
||||
```{rust}
|
||||
let mut x = 5i;
|
||||
let mut x = 5;
|
||||
|
||||
match x {
|
||||
ref mut mr => println!("Got a mutable reference to {}", mr),
|
||||
@ -131,11 +131,11 @@ If you have a struct, you can destructure it inside of a pattern:
|
||||
```{rust}
|
||||
# #![allow(non_shorthand_field_patterns)]
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
let origin = Point { x: 0i, y: 0i };
|
||||
let origin = Point { x: 0, y: 0 };
|
||||
|
||||
match origin {
|
||||
Point { x: x, y: y } => println!("({},{})", x, y),
|
||||
@ -147,11 +147,11 @@ If we only care about some of the values, we don't have to give them all names:
|
||||
```{rust}
|
||||
# #![allow(non_shorthand_field_patterns)]
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
let origin = Point { x: 0i, y: 0i };
|
||||
let origin = Point { x: 0, y: 0 };
|
||||
|
||||
match origin {
|
||||
Point { x: x, .. } => println!("x is {}", x),
|
||||
@ -163,11 +163,11 @@ You can do this kind of match on any member, not just the first:
|
||||
```{rust}
|
||||
# #![allow(non_shorthand_field_patterns)]
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
let origin = Point { x: 0i, y: 0i };
|
||||
let origin = Point { x: 0, y: 0 };
|
||||
|
||||
match origin {
|
||||
Point { y: y, .. } => println!("y is {}", y),
|
||||
|
@ -68,7 +68,7 @@ use rustc::plugin::Registry;
|
||||
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
||||
-> Box<MacResult + 'static> {
|
||||
|
||||
static NUMERALS: &'static [(&'static str, uint)] = &[
|
||||
static NUMERALS: &'static [(&'static str, u32)] = &[
|
||||
("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
|
||||
("C", 100), ("XC", 90), ("L", 50), ("XL", 40),
|
||||
("X", 10), ("IX", 9), ("V", 5), ("IV", 4),
|
||||
@ -83,7 +83,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
||||
};
|
||||
|
||||
let mut text = text.as_slice();
|
||||
let mut total = 0u;
|
||||
let mut total = 0;
|
||||
while !text.is_empty() {
|
||||
match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
|
||||
Some(&(rn, val)) => {
|
||||
@ -118,7 +118,7 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
The advantages over a simple `fn(&str) -> uint` are:
|
||||
The advantages over a simple `fn(&str) -> u32` are:
|
||||
|
||||
* The (arbitrarily complex) conversion is done at compile time.
|
||||
* Input validation is also performed at compile time.
|
||||
|
@ -28,9 +28,10 @@ question](http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-
|
||||
as the rest of this guide assumes you know the difference.) Like this:
|
||||
|
||||
```{rust}
|
||||
let x = 5i;
|
||||
let y = 8i;
|
||||
let x = 5;
|
||||
let y = 8;
|
||||
```
|
||||
|
||||
| location | value |
|
||||
|----------|-------|
|
||||
| 0xd3e030 | 5 |
|
||||
@ -46,10 +47,11 @@ Let's introduce a pointer. In some languages, there is just one type of
|
||||
*reference*, which is the simplest kind of pointer.
|
||||
|
||||
```{rust}
|
||||
let x = 5i;
|
||||
let y = 8i;
|
||||
let x = 5;
|
||||
let y = 8;
|
||||
let z = &y;
|
||||
```
|
||||
|
||||
|location | value |
|
||||
|-------- |----------|
|
||||
|0xd3e030 | 5 |
|
||||
@ -58,12 +60,12 @@ let z = &y;
|
||||
|
||||
See the difference? Rather than contain a value, the value of a pointer is a
|
||||
location in memory. In this case, the location of `y`. `x` and `y` have the
|
||||
type `int`, but `z` has the type `&int`. We can print this location using the
|
||||
type `i32`, but `z` has the type `&i32`. We can print this location using the
|
||||
`{:p}` format string:
|
||||
|
||||
```{rust}
|
||||
let x = 5i;
|
||||
let y = 8i;
|
||||
let x = 5;
|
||||
let y = 8;
|
||||
let z = &y;
|
||||
|
||||
println!("{:p}", z);
|
||||
@ -71,12 +73,12 @@ println!("{:p}", z);
|
||||
|
||||
This would print `0xd3e028`, with our fictional memory addresses.
|
||||
|
||||
Because `int` and `&int` are different types, we can't, for example, add them
|
||||
Because `i32` and `&i32` are different types, we can't, for example, add them
|
||||
together:
|
||||
|
||||
```{rust,ignore}
|
||||
let x = 5i;
|
||||
let y = 8i;
|
||||
let x = 5;
|
||||
let y = 8;
|
||||
let z = &y;
|
||||
|
||||
println!("{}", x + z);
|
||||
@ -85,7 +87,7 @@ println!("{}", x + z);
|
||||
This gives us an error:
|
||||
|
||||
```text
|
||||
hello.rs:6:24: 6:25 error: mismatched types: expected `int` but found `&int` (expected int but found &-ptr)
|
||||
hello.rs:6:24: 6:25 error: mismatched types: expected `i32` but found `&i32` (expected i32 but found &-ptr)
|
||||
hello.rs:6 println!("{}", x + z);
|
||||
^
|
||||
```
|
||||
@ -95,8 +97,8 @@ pointer means accessing the value at the location stored in the pointer. This
|
||||
will work:
|
||||
|
||||
```{rust}
|
||||
let x = 5i;
|
||||
let y = 8i;
|
||||
let x = 5;
|
||||
let y = 8;
|
||||
let z = &y;
|
||||
|
||||
println!("{}", x + *z);
|
||||
@ -153,7 +155,7 @@ So what do pointers have to do with this? Well, since pointers point to a
|
||||
location in memory...
|
||||
|
||||
```text
|
||||
func foo(&int x) {
|
||||
func foo(&i32 x) {
|
||||
*x = 5
|
||||
}
|
||||
|
||||
@ -252,7 +254,7 @@ The most basic type of pointer that Rust has is called a *reference*. Rust
|
||||
references look like this:
|
||||
|
||||
```{rust}
|
||||
let x = 5i;
|
||||
let x = 5;
|
||||
let y = &x;
|
||||
|
||||
println!("{}", *y);
|
||||
@ -269,18 +271,18 @@ referent, because `println!` will automatically dereference it for us.
|
||||
Here's a function that takes a reference:
|
||||
|
||||
```{rust}
|
||||
fn succ(x: &int) -> int { *x + 1 }
|
||||
fn succ(x: &i32) -> i32 { *x + 1 }
|
||||
```
|
||||
|
||||
You can also use `&` as an operator to create a reference, so we can
|
||||
call this function in two different ways:
|
||||
|
||||
```{rust}
|
||||
fn succ(x: &int) -> int { *x + 1 }
|
||||
fn succ(x: &i32) -> i32 { *x + 1 }
|
||||
|
||||
fn main() {
|
||||
|
||||
let x = 5i;
|
||||
let x = 5;
|
||||
let y = &x;
|
||||
|
||||
println!("{}", succ(y));
|
||||
@ -294,13 +296,13 @@ Of course, if this were real code, we wouldn't bother with the reference, and
|
||||
just write:
|
||||
|
||||
```{rust}
|
||||
fn succ(x: int) -> int { x + 1 }
|
||||
fn succ(x: i32) -> i32 { x + 1 }
|
||||
```
|
||||
|
||||
References are immutable by default:
|
||||
|
||||
```{rust,ignore}
|
||||
let x = 5i;
|
||||
let x = 5;
|
||||
let y = &x;
|
||||
|
||||
*y = 5; // error: cannot assign to immutable dereference of `&`-pointer `*y`
|
||||
@ -310,21 +312,21 @@ They can be made mutable with `mut`, but only if its referent is also mutable.
|
||||
This works:
|
||||
|
||||
```{rust}
|
||||
let mut x = 5i;
|
||||
let mut x = 5;
|
||||
let y = &mut x;
|
||||
```
|
||||
|
||||
This does not:
|
||||
|
||||
```{rust,ignore}
|
||||
let x = 5i;
|
||||
let x = 5;
|
||||
let y = &mut x; // error: cannot borrow immutable local variable `x` as mutable
|
||||
```
|
||||
|
||||
Immutable pointers are allowed to alias:
|
||||
|
||||
```{rust}
|
||||
let x = 5i;
|
||||
let x = 5;
|
||||
let y = &x;
|
||||
let z = &x;
|
||||
```
|
||||
@ -332,7 +334,7 @@ let z = &x;
|
||||
Mutable ones, however, are not:
|
||||
|
||||
```{rust,ignore}
|
||||
let mut x = 5i;
|
||||
let mut x = 5;
|
||||
let y = &mut x;
|
||||
let z = &mut x; // error: cannot borrow `x` as mutable more than once at a time
|
||||
```
|
||||
@ -359,7 +361,7 @@ duration a *lifetime*. Let's try a more complex example:
|
||||
|
||||
```{rust}
|
||||
fn main() {
|
||||
let x = &mut 5i;
|
||||
let x = &mut 5;
|
||||
|
||||
if *x < 10 {
|
||||
let y = &x;
|
||||
@ -380,7 +382,7 @@ mutated, and therefore, lets us pass. This wouldn't work:
|
||||
|
||||
```{rust,ignore}
|
||||
fn main() {
|
||||
let x = &mut 5i;
|
||||
let x = &mut 5;
|
||||
|
||||
if *x < 10 {
|
||||
let y = &x;
|
||||
@ -425,13 +427,13 @@ References just borrow ownership, which is more polite if you don't need the
|
||||
ownership. In other words, prefer:
|
||||
|
||||
```{rust}
|
||||
fn succ(x: &int) -> int { *x + 1 }
|
||||
fn succ(x: &i32) -> i32 { *x + 1 }
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```{rust}
|
||||
fn succ(x: Box<int>) -> int { *x + 1 }
|
||||
fn succ(x: Box<i32>) -> i32 { *x + 1 }
|
||||
```
|
||||
|
||||
As a corollary to that rule, references allow you to accept a wide variety of
|
||||
@ -439,7 +441,7 @@ other pointers, and so are useful so that you don't have to write a number
|
||||
of variants per pointer. In other words, prefer:
|
||||
|
||||
```{rust}
|
||||
fn succ(x: &int) -> int { *x + 1 }
|
||||
fn succ(x: &i32) -> i32 { *x + 1 }
|
||||
```
|
||||
|
||||
to
|
||||
@ -447,9 +449,9 @@ to
|
||||
```{rust}
|
||||
use std::rc::Rc;
|
||||
|
||||
fn box_succ(x: Box<int>) -> int { *x + 1 }
|
||||
fn box_succ(x: Box<i32>) -> i32 { *x + 1 }
|
||||
|
||||
fn rc_succ(x: Rc<int>) -> int { *x + 1 }
|
||||
fn rc_succ(x: Rc<i32>) -> i32 { *x + 1 }
|
||||
```
|
||||
|
||||
Note that the caller of your function will have to modify their calls slightly:
|
||||
@ -457,11 +459,11 @@ Note that the caller of your function will have to modify their calls slightly:
|
||||
```{rust}
|
||||
use std::rc::Rc;
|
||||
|
||||
fn succ(x: &int) -> int { *x + 1 }
|
||||
fn succ(x: &i32) -> i32 { *x + 1 }
|
||||
|
||||
let ref_x = &5i;
|
||||
let box_x = Box::new(5i);
|
||||
let rc_x = Rc::new(5i);
|
||||
let ref_x = &5;
|
||||
let box_x = Box::new(5);
|
||||
let rc_x = Rc::new(5);
|
||||
|
||||
succ(ref_x);
|
||||
succ(&*box_x);
|
||||
@ -477,7 +479,7 @@ those contents.
|
||||
heap allocation in Rust. Creating a box looks like this:
|
||||
|
||||
```{rust}
|
||||
let x = Box::new(5i);
|
||||
let x = Box::new(5);
|
||||
```
|
||||
|
||||
Boxes are heap allocated and they are deallocated automatically by Rust when
|
||||
@ -485,7 +487,7 @@ they go out of scope:
|
||||
|
||||
```{rust}
|
||||
{
|
||||
let x = Box::new(5i);
|
||||
let x = Box::new(5);
|
||||
|
||||
// stuff happens
|
||||
|
||||
@ -505,7 +507,7 @@ boxes, though. As a rough approximation, you can treat this Rust code:
|
||||
|
||||
```{rust}
|
||||
{
|
||||
let x = Box::new(5i);
|
||||
let x = Box::new(5);
|
||||
|
||||
// stuff happens
|
||||
}
|
||||
@ -544,12 +546,12 @@ for more detail on how lifetimes work.
|
||||
Using boxes and references together is very common. For example:
|
||||
|
||||
```{rust}
|
||||
fn add_one(x: &int) -> int {
|
||||
fn add_one(x: &i32) -> i32 {
|
||||
*x + 1
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Box::new(5i);
|
||||
let x = Box::new(5);
|
||||
|
||||
println!("{}", add_one(&*x));
|
||||
}
|
||||
@ -561,12 +563,12 @@ function, and since it's only reading the value, allows it.
|
||||
We can borrow `x` multiple times, as long as it's not simultaneous:
|
||||
|
||||
```{rust}
|
||||
fn add_one(x: &int) -> int {
|
||||
fn add_one(x: &i32) -> i32 {
|
||||
*x + 1
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Box::new(5i);
|
||||
let x = Box::new(5);
|
||||
|
||||
println!("{}", add_one(&*x));
|
||||
println!("{}", add_one(&*x));
|
||||
@ -577,12 +579,12 @@ fn main() {
|
||||
Or as long as it's not a mutable borrow. This will error:
|
||||
|
||||
```{rust,ignore}
|
||||
fn add_one(x: &mut int) -> int {
|
||||
fn add_one(x: &mut i32) -> i32 {
|
||||
*x + 1
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Box::new(5i);
|
||||
let x = Box::new(5);
|
||||
|
||||
println!("{}", add_one(&*x)); // error: cannot borrow immutable dereference
|
||||
// of `&`-pointer as mutable
|
||||
@ -610,7 +612,7 @@ enum List<T> {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let list: List<int> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
|
||||
let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
|
||||
println!("{:?}", list);
|
||||
}
|
||||
```
|
||||
@ -659,10 +661,10 @@ so as to avoid copying a large data structure. For example:
|
||||
|
||||
```{rust}
|
||||
struct BigStruct {
|
||||
one: int,
|
||||
two: int,
|
||||
one: i32,
|
||||
two: i32,
|
||||
// etc
|
||||
one_hundred: int,
|
||||
one_hundred: i32,
|
||||
}
|
||||
|
||||
fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
|
||||
@ -687,10 +689,10 @@ This is an antipattern in Rust. Instead, write this:
|
||||
|
||||
```{rust}
|
||||
struct BigStruct {
|
||||
one: int,
|
||||
two: int,
|
||||
one: i32,
|
||||
two: i32,
|
||||
// etc
|
||||
one_hundred: int,
|
||||
one_hundred: i32,
|
||||
}
|
||||
|
||||
fn foo(x: Box<BigStruct>) -> BigStruct {
|
||||
|
@ -512,7 +512,7 @@ use test::Bencher;
|
||||
#[bench]
|
||||
fn bench_xor_1000_ints(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
range(0u, 1000).fold(0, |old, new| old ^ new);
|
||||
range(0, 1000).fold(0, |old, new| old ^ new);
|
||||
});
|
||||
}
|
||||
```
|
||||
@ -537,7 +537,7 @@ computation entirely. This could be done for the example above by adjusting the
|
||||
# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
|
||||
b.iter(|| {
|
||||
// note lack of `;` (could also use an explicit `return`).
|
||||
range(0u, 1000).fold(0, |old, new| old ^ new)
|
||||
range(0, 1000).fold(0, |old, new| old ^ new)
|
||||
});
|
||||
```
|
||||
|
||||
|
@ -224,7 +224,7 @@ use std::sync::Future;
|
||||
# fn main() {
|
||||
# fn make_a_sandwich() {};
|
||||
fn fib(n: u64) -> u64 {
|
||||
// lengthy computation returning an uint
|
||||
// lengthy computation returning an 64
|
||||
12586269025
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ computations. The workload will be distributed on the available cores.
|
||||
# #![allow(deprecated)]
|
||||
# use std::num::Float;
|
||||
# use std::sync::Future;
|
||||
fn partial_sum(start: uint) -> f64 {
|
||||
fn partial_sum(start: u64) -> f64 {
|
||||
let mut local_sum = 0f64;
|
||||
for num in range(start*100000, (start+1)*100000) {
|
||||
local_sum += (num as f64 + 1.0).powf(-2.0);
|
||||
@ -289,7 +289,7 @@ use std::num::Float;
|
||||
use std::rand;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn pnorm(nums: &[f64], p: uint) -> f64 {
|
||||
fn pnorm(nums: &[f64], p: u64) -> f64 {
|
||||
nums.iter().fold(0.0, |a, b| a + b.powf(p as f64)).powf(1.0 / (p as f64))
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ fn main() {
|
||||
let numbers = Vec::from_fn(1000000, |_| rand::random::<f64>());
|
||||
let numbers_arc = Arc::new(numbers);
|
||||
|
||||
for num in range(1u, 10) {
|
||||
for num in range(1, 10) {
|
||||
let thread_numbers = numbers_arc.clone();
|
||||
|
||||
spawn(move || {
|
||||
@ -328,7 +328,7 @@ if it were local.
|
||||
```{rust,ignore}
|
||||
# use std::rand;
|
||||
# use std::sync::Arc;
|
||||
# fn pnorm(nums: &[f64], p: uint) -> f64 { 4.0 }
|
||||
# fn pnorm(nums: &[f64], p: u64) -> f64 { 4.0 }
|
||||
# fn main() {
|
||||
# let numbers=Vec::from_fn(1000000, |_| rand::random::<f64>());
|
||||
# let numbers_arc = Arc::new(numbers);
|
||||
@ -357,16 +357,16 @@ each other if they panic. The simplest way of handling a panic is with the
|
||||
`try` function, which is similar to `spawn`, but immediately blocks and waits
|
||||
for the child thread to finish. `try` returns a value of type
|
||||
`Result<T, Box<Any + Send>>`. `Result` is an `enum` type with two variants:
|
||||
`Ok` and `Err`. In this case, because the type arguments to `Result` are `int`
|
||||
`Ok` and `Err`. In this case, because the type arguments to `Result` are `i32`
|
||||
and `()`, callers can pattern-match on a result to check whether it's an `Ok`
|
||||
result with an `int` field (representing a successful result) or an `Err` result
|
||||
result with an `i32` field (representing a successful result) or an `Err` result
|
||||
(representing termination with an error).
|
||||
|
||||
```{rust,ignore}
|
||||
# use std::thread::Thread;
|
||||
# fn some_condition() -> bool { false }
|
||||
# fn calculate_result() -> int { 0 }
|
||||
let result: Result<int, Box<std::any::Any + Send>> = Thread::spawn(move || {
|
||||
# fn calculate_result() -> i32 { 0 }
|
||||
let result: Result<i32, Box<std::any::Any + Send>> = Thread::spawn(move || {
|
||||
if some_condition() {
|
||||
calculate_result()
|
||||
} else {
|
||||
|
@ -145,7 +145,7 @@ As you can see, `print_area` is now generic, but also ensures that we
|
||||
have passed in the correct types. If we pass in an incorrect type:
|
||||
|
||||
```{rust,ignore}
|
||||
print_area(5i);
|
||||
print_area(5);
|
||||
```
|
||||
|
||||
We get a compile-time error:
|
||||
@ -156,14 +156,14 @@ error: failed to find an implementation of trait main::HasArea for int
|
||||
|
||||
So far, we've only added trait implementations to structs, but you can
|
||||
implement a trait for any type. So technically, we _could_ implement
|
||||
`HasArea` for `int`:
|
||||
`HasArea` for `i32`:
|
||||
|
||||
```{rust}
|
||||
trait HasArea {
|
||||
fn area(&self) -> f64;
|
||||
}
|
||||
|
||||
impl HasArea for int {
|
||||
impl HasArea for i32 {
|
||||
fn area(&self) -> f64 {
|
||||
println!("this is silly");
|
||||
|
||||
@ -171,7 +171,7 @@ impl HasArea for int {
|
||||
}
|
||||
}
|
||||
|
||||
5i.area();
|
||||
5.area();
|
||||
```
|
||||
|
||||
It is considered poor style to implement methods on such primitive types, even
|
||||
@ -264,8 +264,8 @@ it won't affect you, unless you `use` that trait.
|
||||
|
||||
There's one more restriction on implementing traits. Either the trait or the
|
||||
type you're writing the `impl` for must be inside your crate. So, we could
|
||||
implement the `HasArea` type for `int`, because `HasArea` is in our crate. But
|
||||
if we tried to implement `Float`, a trait provided by Rust, for `int`, we could
|
||||
implement the `HasArea` type for `i32`, because `HasArea` is in our crate. But
|
||||
if we tried to implement `Float`, a trait provided by Rust, for `i32`, we could
|
||||
not, because both the trait and the type aren't in our crate.
|
||||
|
||||
One last thing about traits: generic functions with a trait bound use
|
||||
|
@ -95,7 +95,7 @@ offered by the Rust language and libraries. For example, they
|
||||
use-after-free;
|
||||
- are considered sendable (if their contents is considered sendable),
|
||||
so the compiler offers no assistance with ensuring their use is
|
||||
thread-safe; for example, one can concurrently access a `*mut int`
|
||||
thread-safe; for example, one can concurrently access a `*mut i32`
|
||||
from two threads without synchronization.
|
||||
- lack any form of lifetimes, unlike `&`, and so the compiler cannot
|
||||
reason about dangling pointers; and
|
||||
@ -265,12 +265,12 @@ impl<T: Send> Drop for Unique<T> {
|
||||
// A comparison between the built-in `Box` and this reimplementation
|
||||
fn main() {
|
||||
{
|
||||
let mut x = Box::new(5i);
|
||||
let mut x = Box::new(5);
|
||||
*x = 10;
|
||||
} // `x` is freed here
|
||||
|
||||
{
|
||||
let mut y = Unique::new(5i);
|
||||
let mut y = Unique::new(5);
|
||||
*y.borrow_mut() = 10;
|
||||
} // `y` is freed here
|
||||
}
|
||||
@ -367,7 +367,7 @@ expressions must be mutable lvalues:
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn add(a: int, b: int) -> int {
|
||||
fn add(a: i32, b: i32) -> i32 {
|
||||
let mut c = 0;
|
||||
unsafe {
|
||||
asm!("add $2, $0"
|
||||
@ -378,7 +378,7 @@ fn add(a: int, b: int) -> int {
|
||||
c
|
||||
}
|
||||
# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
# fn add(a: int, b: int) -> int { a + b }
|
||||
# fn add(a: i32, b: i32) -> i32 { a + b }
|
||||
|
||||
fn main() {
|
||||
assert_eq!(add(3, 14159), 14162)
|
||||
@ -454,7 +454,7 @@ extern crate libc;
|
||||
|
||||
// Entry point for this program
|
||||
#[start]
|
||||
fn start(_argc: int, _argv: *const *const u8) -> int {
|
||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
0
|
||||
}
|
||||
|
||||
@ -480,7 +480,7 @@ compiler's name mangling too:
|
||||
extern crate libc;
|
||||
|
||||
#[no_mangle] // ensure that this symbol is called `main` in the output
|
||||
pub extern fn main(argc: int, argv: *const *const u8) -> int {
|
||||
pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
@ -552,8 +552,8 @@ pub extern fn dot_product(a: *const u32, a_len: u32,
|
||||
// cannot tell the pointers are valid.
|
||||
let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
|
||||
mem::transmute((
|
||||
Slice { data: a, len: a_len as uint },
|
||||
Slice { data: b, len: b_len as uint },
|
||||
Slice { data: a, len: a_len as usize },
|
||||
Slice { data: b, len: b_len as usize },
|
||||
))
|
||||
};
|
||||
|
||||
@ -568,13 +568,13 @@ pub extern fn dot_product(a: *const u32, a_len: u32,
|
||||
#[lang = "panic_fmt"]
|
||||
extern fn panic_fmt(args: &core::fmt::Arguments,
|
||||
file: &str,
|
||||
line: uint) -> ! {
|
||||
line: u32) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
# #[start] fn start(argc: int, argv: *const *const u8) -> int { 0 }
|
||||
# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
@ -628,7 +628,7 @@ via a declaration like
|
||||
extern "rust-intrinsic" {
|
||||
fn transmute<T, U>(x: T) -> U;
|
||||
|
||||
fn offset<T>(dst: *const T, offset: int) -> *const T;
|
||||
fn offset<T>(dst: *const T, offset: isize) -> *const T;
|
||||
}
|
||||
```
|
||||
|
||||
@ -665,24 +665,24 @@ extern {
|
||||
pub struct Box<T>(*mut T);
|
||||
|
||||
#[lang="exchange_malloc"]
|
||||
unsafe fn allocate(size: uint, _align: uint) -> *mut u8 {
|
||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
||||
let p = libc::malloc(size as libc::size_t) as *mut u8;
|
||||
|
||||
// malloc failed
|
||||
if p as uint == 0 {
|
||||
if p as usize == 0 {
|
||||
abort();
|
||||
}
|
||||
|
||||
p
|
||||
}
|
||||
#[lang="exchange_free"]
|
||||
unsafe fn deallocate(ptr: *mut u8, _size: uint, _align: uint) {
|
||||
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
|
||||
libc::free(ptr as *mut libc::c_void)
|
||||
}
|
||||
|
||||
#[start]
|
||||
fn main(argc: int, argv: *const *const u8) -> int {
|
||||
let x = box 1i;
|
||||
fn main(argc: isize, argv: *const *const u8) -> isize {
|
||||
let x = box 1;
|
||||
|
||||
0
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user