Fixed code snippets
This commit is contained in:
parent
7cfce50b24
commit
1fd4c3bb40
@ -21,7 +21,7 @@ fn succ(x: &int) -> int { *x + 1 }
|
||||
|
||||
So I wrote this code to try it out:
|
||||
|
||||
~~~rust {.xfail-test}
|
||||
~~~rust{.xfail-test}
|
||||
fn main() {
|
||||
let number = 5;
|
||||
let succ_number = succ(number);
|
||||
@ -73,7 +73,7 @@ However.
|
||||
Here are the use-cases for pointers. I've prefixed them with the name of the
|
||||
pointer that satisfies that use-case:
|
||||
|
||||
1. Owned: ~Trait must be a pointer, becuase you don't know the size of the
|
||||
1. Owned: ~Trait must be a pointer, because you don't know the size of the
|
||||
object, so indirection is mandatory.
|
||||
2. Owned: You need a recursive data structure. These can be infinite sized, so
|
||||
indirection is mandatory.
|
||||
@ -85,18 +85,18 @@ common, such as C++, please read "A note..." below.
|
||||
or impossible. This is only often useful when a program is very large or very
|
||||
complicated. Using a managed pointer will activate Rust's garbage collection
|
||||
mechanism.
|
||||
5: Reference: You're writing a function, and you need a pointer, but you don't
|
||||
5. Reference: You're writing a function, and you need a pointer, but you don't
|
||||
care about its ownership. If you make the argument a reference, callers
|
||||
can send in whatever kind they want.
|
||||
|
||||
Five exceptions. That's it. Otherwise, you shouldn't need them. Be skeptical
|
||||
Five exceptions. That's it. Otherwise, you shouldn't need them. Be sceptical
|
||||
of pointers in Rust: use them for a deliberate purpose, not just to make the
|
||||
compiler happy.
|
||||
|
||||
## A note for those proficient in pointers
|
||||
|
||||
If you're coming to Rust from a language like C or C++, you may be used to
|
||||
passing things by reference, or passing things by pointer. In some langauges,
|
||||
passing things by reference, or passing things by pointer. In some languages,
|
||||
like Java, you can't even have objects without a pointer to them. Therefore, if
|
||||
you were writing this Rust code:
|
||||
|
||||
@ -150,7 +150,7 @@ fn main() {
|
||||
}
|
||||
~~~
|
||||
|
||||
But won't this be inefficent? Well, that's a complicated question, but it's
|
||||
But won't this be inefficient? Well, that's a complicated question, but it's
|
||||
important to know that Rust, like C and C++, store aggregate data types
|
||||
'unboxed,' whereas languages like Java and Ruby store these types as 'boxed.'
|
||||
For smaller structs, this way will be more efficient. For larger ones, it may
|
||||
@ -173,7 +173,7 @@ These two properties make for three use cases.
|
||||
|
||||
## References to Traits
|
||||
|
||||
Traits must be referenced through a pointer, becuase the struct that implements
|
||||
Traits must be referenced through a pointer, because the struct that implements
|
||||
the trait may be a different size than a different struct that implements the
|
||||
trait. Therefore, unboxed traits don't make any sense, and aren't allowed.
|
||||
|
||||
@ -199,7 +199,7 @@ This prints:
|
||||
Cons(1, ~Cons(2, ~Cons(3, ~Nil)))
|
||||
~~~
|
||||
|
||||
The inner lists _must_ be an owned pointer, becuase we can't know how many
|
||||
The inner lists _must_ be an owned pointer, because we can't know how many
|
||||
elements are in the list. Without knowing the length, we don't know the size,
|
||||
and therefore require the indirection that pointers offer.
|
||||
|
||||
@ -261,7 +261,7 @@ program is very large and complicated.
|
||||
|
||||
For example, let's say you're using an owned pointer, and you want to do this:
|
||||
|
||||
~~~rust {.xfail-test}
|
||||
~~~rust{.xfail-test}
|
||||
struct Point {
|
||||
x: int,
|
||||
y: int,
|
||||
@ -315,7 +315,7 @@ managed pointers:
|
||||
1. They activate Rust's garbage collector. Other pointer types don't share this
|
||||
drawback.
|
||||
2. You cannot pass this data to another task. Shared ownership across
|
||||
concurrency boundaries is the source of endless pain in other langauges, so
|
||||
concurrency boundaries is the source of endless pain in other languages, so
|
||||
Rust does not let you do this.
|
||||
|
||||
# References
|
||||
@ -355,7 +355,7 @@ takes in two references, but we give it a managed and unique pointer. Of
|
||||
course, if this were a real program, we wouldn't have any of these pointers,
|
||||
they're just there to demonstrate the concepts.
|
||||
|
||||
So how is this hard? Well, because we're igorning ownership, the compiler needs
|
||||
So how is this hard? Well, because we're ignoring ownership, the compiler needs
|
||||
to take great care to make sure that everything is safe. Despite their complete
|
||||
safety, a reference's representation at runtime is the same as that of
|
||||
an ordinary pointer in a C program. They introduce zero overhead. The compiler
|
||||
@ -365,14 +365,14 @@ This theory is called 'region pointers,' and involve a concept called
|
||||
'lifetimes'. Here's the simple explanation: would you expect this code to
|
||||
compile?
|
||||
|
||||
~~~rust {.xfail-test}
|
||||
~~~rust{.xfail-test}
|
||||
fn main() {
|
||||
println(x.to_str());
|
||||
let x = 5;
|
||||
}
|
||||
~~~
|
||||
|
||||
Probably not. That's becuase you know that the name `x` is valid from where
|
||||
Probably not. That's because you know that the name `x` is valid from where
|
||||
it's declared to when it goes out of scope. In this case, that's the end of
|
||||
the `main` function. So you know this code will cause an error. We call this
|
||||
duration a 'lifetime'. Let's try a more complex example:
|
||||
@ -394,7 +394,7 @@ Here, we're borrowing a pointer to `x` inside of the `if`. The compiler, however
|
||||
is able to determine that that pointer will go out of scope without `x` being
|
||||
mutated, and therefore, lets us pass. This wouldn't work:
|
||||
|
||||
~~~rust {.xfail-test}
|
||||
~~~rust{.xfail-test}
|
||||
fn main() {
|
||||
let mut x = ~5;
|
||||
if *x < 10 {
|
||||
@ -427,7 +427,7 @@ great detail, so if you want the full details, check that out.
|
||||
|
||||
# Returning Pointers
|
||||
|
||||
We've talked a lot about funtions that accept various kinds of pointers, but
|
||||
We've talked a lot about functions that accept various kinds of pointers, but
|
||||
what about returning them? Here's the rule of thumb: only return a unique or
|
||||
managed pointer if you were given one in the first place.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user