From 2891f5abe3c7f455d16930a35bfc8d8d623de0ff Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 26 Sep 2012 16:41:14 -0700 Subject: [PATCH] tutorial: Remove all references to 'records'. Misc --- doc/tutorial-borrowed-ptr.md | 23 +++++++++++++---------- doc/tutorial-ffi.md | 18 ++++++++++++------ doc/tutorial.md | 32 ++++++++++++++++---------------- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/doc/tutorial-borrowed-ptr.md b/doc/tutorial-borrowed-ptr.md index 8def9762bce..8023f9365a5 100644 --- a/doc/tutorial-borrowed-ptr.md +++ b/doc/tutorial-borrowed-ptr.md @@ -29,10 +29,10 @@ a limit duration. Borrowed pointers never claim any kind of ownership over the data that they point at: instead, they are used for cases where you like to make use of data for a short time. -As an example, consider a simple record type `point`: +As an example, consider a simple struct type `point`: ~~~ -type point = {x: float, y: float}; +struct point {x: float, y: float} ~~~ We can use this simple definition to allocate points in many ways. For @@ -82,7 +82,7 @@ compute_distance(shared_box, unique_box); Here the `&` operator is used to take the address of the variable `on_the_stack`; this is because `on_the_stack` has the type `point` -(that is, a record value) and we have to take its address to get a +(that is, a struct value) and we have to take its address to get a value. We also call this _borrowing_ the local variable `on_the_stack`, because we are created an alias: that is, another route to the same data. @@ -325,15 +325,18 @@ which has been freed. In fact, the compiler can apply this same kind of reasoning can be applied to any memory which is _(uniquely) owned by the stack frame_. So we could modify the previous example to introduce -additional unique pointers and records, and the compiler will still be +additional unique pointers and structs, and the compiler will still be able to detect possible mutations: ~~~ {.xfail-test} fn example3() -> int { - let mut x = ~{mut f: ~{g: 3}}; + struct R { g: int } + struct S { mut f: ~R } + + let mut x = ~S {mut f: ~R {g: 3}}; let y = &x.f.g; - x = ~{mut f: ~{g: 4}}; // Error reported here. - x.f = ~{g: 5}; // Error reported here. + x = ~S {mut f: ~R {g: 4}}; // Error reported here. + x.f = ~R {g: 5}; // Error reported here. *y } ~~~ @@ -504,7 +507,7 @@ Stack Memory ~~~ As you can see, the `size` pointer would not be pointing at a `float` and -not a record. This is not good. +not a struct. This is not good. So, in fact, for every `ref` binding, the compiler will impose the same rules as the ones we saw for borrowing the interior of a unique @@ -559,14 +562,14 @@ defined by the caller. In any case, whatever the lifetime L is, the pointer produced by `&p.x` always has the same lifetime as `p` itself, as a pointer to a -field of a record is valid as long as the record is valid. Therefore, +field of a struct is valid as long as the struct is valid. Therefore, the compiler is satisfied with the function `get_x()`. To drill in this point, let’s look at a variation on the example, this time one which does not compile: ~~~ {.xfail-test} -type point = {x: float, y: float}; +struct point {x: float, y: float} fn get_x_sh(p: @point) -> &float { &p.x // Error reported here } diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index 42c5908b049..b7e39390168 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -205,7 +205,7 @@ vector. ## Passing structures C functions often take pointers to structs as arguments. Since Rust -records are binary-compatible with C structs, Rust programs can call +structs are binary-compatible with C structs, Rust programs can call such functions directly. This program uses the POSIX function `gettimeofday` to get a @@ -215,14 +215,20 @@ microsecond-resolution timer. extern mod std; use libc::c_ulonglong; -type timeval = {mut tv_sec: c_ulonglong, - mut tv_usec: c_ulonglong}; +struct timeval { + mut tv_sec: c_ulonglong, + mut tv_usec: c_ulonglong +} + #[nolink] extern mod lib_c { fn gettimeofday(tv: *timeval, tz: *()) -> i32; } fn unix_time_in_microseconds() -> u64 unsafe { - let x = {mut tv_sec: 0 as c_ulonglong, mut tv_usec: 0 as c_ulonglong}; + let x = timeval { + mut tv_sec: 0 as c_ulonglong, + mut tv_usec: 0 as c_ulonglong + }; lib_c::gettimeofday(ptr::addr_of(x), ptr::null()); return (x.tv_sec as u64) * 1000_000_u64 + (x.tv_usec as u64); } @@ -234,8 +240,8 @@ The `#[nolink]` attribute indicates that there's no foreign library to link in. The standard C library is already linked with Rust programs. A `timeval`, in C, is a struct with two 32-bit integers. Thus, we -define a record type with the same contents, and declare -`gettimeofday` to take a pointer to such a record. +define a struct type with the same contents, and declare +`gettimeofday` to take a pointer to such a struct. The second argument to `gettimeofday` (the time zone) is not used by this program, so it simply declares it to be a pointer to the nil diff --git a/doc/tutorial.md b/doc/tutorial.md index 99b858cb2cf..7244206b2eb 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -713,16 +713,16 @@ enum Shape { } ~~~~ -A value of this type is either a Circle, in which case it contains a -point struct and a float, or a Rectangle, in which case it contains -two point records. The run-time representation of such a value +A value of this type is either a `Circle`, in which case it contains a +`Point` struct and a float, or a `Rectangle`, in which case it contains +two `Point` structs. The run-time representation of such a value includes an identifier of the actual form that it holds, much like the 'tagged union' pattern in C, but with better ergonomics. -The above declaration will define a type `shape` that can be used to -refer to such shapes, and two functions, `circle` and `rectangle`, +The above declaration will define a type `Shape` that can be used to +refer to such shapes, and two functions, `Circle` and `Rectangle`, which can be used to construct values of the type (taking arguments of -the specified types). So `circle({x: 0f, y: 0f}, 10f)` is the way to +the specified types). So `Circle(Point {x: 0f, y: 0f}, 10f)` is the way to create a new circle. Enum variants need not have type parameters. This, for example, is @@ -820,7 +820,7 @@ fn point_from_direction(dir: Direction) -> Point { ## Tuples -Tuples in Rust behave exactly like records, except that their fields +Tuples in Rust behave exactly like structs, except that their fields do not have names (and can thus not be accessed with dot notation). Tuples can have any arity except for 0 or 1 (though you may consider nil, `()`, as the empty tuple if you like). @@ -1006,16 +1006,16 @@ of each is key to using Rust effectively. # Boxes and pointers -In contrast to a lot of modern languages, aggregate types like records +In contrast to a lot of modern languages, aggregate types like structs and enums are _not_ represented as pointers to allocated memory in Rust. They are, as in C and C++, represented directly. This means that -if you `let x = {x: 1f, y: 1f};`, you are creating a record on the -stack. If you then copy it into a data structure, the whole record is +if you `let x = Point {x: 1f, y: 1f};`, you are creating a struct on the +stack. If you then copy it into a data structure, the whole struct is copied, not just a pointer. -For small records like `point`, this is usually more efficient than -allocating memory and going through a pointer. But for big records, or -records with mutable fields, it can be useful to have a single copy on +For small structs like `Point`, this is usually more efficient than +allocating memory and going through a pointer. But for big structs, or +those with mutable fields, it can be useful to have a single copy on the heap, and refer to that through a pointer. Rust supports several types of pointers. The safe pointer types are @@ -1191,8 +1191,8 @@ compute_distance(shared_box, unique_box); ~~~ Here the `&` operator is used to take the address of the variable -`on_the_stack`; this is because `on_the_stack` has the type `point` -(that is, a record value) and we have to take its address to get a +`on_the_stack`; this is because `on_the_stack` has the type `Point` +(that is, a struct value) and we have to take its address to get a value. We also call this _borrowing_ the local variable `on_the_stack`, because we are created an alias: that is, another route to the same data. @@ -1517,7 +1517,7 @@ fn each(v: &[int], op: fn(v: &int)) { The reason we pass in a *pointer* to an integer rather than the integer itself is that this is how the actual `each()` function for vectors works. Using a pointer means that the function can be used -for vectors of any type, even large records that would be impractical +for vectors of any type, even large structs that would be impractical to copy out of the vector on each iteration. As a caller, if we use a closure to provide the final operator argument, we can write it in a way that has a pleasant, block-like structure.