@@ -2033,7 +2033,7 @@ console, with a single method:
2033
2033
2034
2034
~~~~
2035
2035
trait Printable {
2036
- fn print();
2036
+ fn print(&self );
2037
2037
}
2038
2038
~~~~
2039
2039
@@ -2045,13 +2045,13 @@ and `~str`.
2045
2045
[ impls ] : #functions-and-methods
2046
2046
2047
2047
~~~~
2048
- # trait Printable { fn print(); }
2048
+ # trait Printable { fn print(&self ); }
2049
2049
impl int: Printable {
2050
- fn print() { io::println(fmt!("%d", self)) }
2050
+ fn print(&self ) { io::println(fmt!("%d", * self)) }
2051
2051
}
2052
2052
2053
2053
impl &str: Printable {
2054
- fn print() { io::println(self) }
2054
+ fn print(&self ) { io::println(* self) }
2055
2055
}
2056
2056
2057
2057
# 1.print();
@@ -2065,14 +2065,14 @@ types might look like the following:
2065
2065
2066
2066
~~~~
2067
2067
trait Seq<T> {
2068
- fn len() -> uint;
2069
- fn iter(b: fn(v: &T));
2068
+ fn len(&self ) -> uint;
2069
+ fn iter(&self, b: fn(v: &T));
2070
2070
}
2071
2071
2072
2072
impl<T> ~[T]: Seq<T> {
2073
- fn len() -> uint { vec::len(self) }
2074
- fn iter(b: fn(v: &T)) {
2075
- for vec::each(self) |elt| { b(elt); }
2073
+ fn len(&self ) -> uint { vec::len(* self) }
2074
+ fn iter(&self, b: fn(v: &T)) {
2075
+ for vec::each(* self) |elt| { b(elt); }
2076
2076
}
2077
2077
}
2078
2078
~~~~
@@ -2096,21 +2096,22 @@ trait, `self` is a type, and in an impl, `self` is a value. The
2096
2096
following trait describes types that support an equality operation:
2097
2097
2098
2098
~~~~
2099
- // In a trait, `self` refers to the type implementing the trait
2099
+ // In a trait, `self` refers both to the self argument
2100
+ // and to the type implementing the trait
2100
2101
trait Eq {
2101
- fn equals(other: &self) -> bool;
2102
+ fn equals(&self, other: &self) -> bool;
2102
2103
}
2103
2104
2104
- // In an impl, `self` refers to the value of the receiver
2105
+ // In an impl, `self` refers just to the value of the receiver
2105
2106
impl int: Eq {
2106
- fn equals(other: &int) -> bool { *other == self }
2107
+ fn equals(&self, other: &int) -> bool { *other == * self }
2107
2108
}
2108
2109
~~~~
2109
2110
2110
- Notice that in the trait definition, ` equals ` takes a parameter of
2111
- type ` self ` . In contrast, in the ` impl ` , ` equals ` takes a parameter of
2112
- type ` int ` , and uses ` self ` as the name of the receiver (analogous to
2113
- the ` this ` pointer in C++) .
2111
+ Notice that in the trait definition, ` equals ` takes a
2112
+ second parameter of type ` self ` .
2113
+ In contrast, in the ` impl ` , ` equals ` takes a second parameter of
2114
+ type ` int ` , only using ` self ` as the name of the receiver .
2114
2115
2115
2116
## Bounded type parameters and static method dispatch
2116
2117
@@ -2120,7 +2121,7 @@ define _bounds_ on type parameters, so that we can then operate on
2120
2121
generic types.
2121
2122
2122
2123
~~~~
2123
- # trait Printable { fn print(); }
2124
+ # trait Printable { fn print(&self ); }
2124
2125
fn print_all<T: Printable>(printable_things: ~[T]) {
2125
2126
for printable_things.each |thing| {
2126
2127
thing.print();
@@ -2138,7 +2139,7 @@ Type parameters can have multiple bounds by separating them with spaces,
2138
2139
as in this version of ` print_all ` that copies elements.
2139
2140
2140
2141
~~~
2141
- # trait Printable { fn print(); }
2142
+ # trait Printable { fn print(&self ); }
2142
2143
fn print_all<T: Printable Copy>(printable_things: ~[T]) {
2143
2144
let mut i = 0;
2144
2145
while i < printable_things.len() {
@@ -2163,9 +2164,9 @@ However, consider this function:
2163
2164
2164
2165
~~~~
2165
2166
# type Circle = int; type Rectangle = int;
2166
- # impl int: Drawable { fn draw() {} }
2167
+ # impl int: Drawable { fn draw(&self ) {} }
2167
2168
# fn new_circle() -> int { 1 }
2168
- trait Drawable { fn draw(); }
2169
+ trait Drawable { fn draw(&self ); }
2169
2170
2170
2171
fn draw_all<T: Drawable>(shapes: ~[T]) {
2171
2172
for shapes.each |shape| { shape.draw(); }
@@ -2181,7 +2182,7 @@ needed, a trait name can alternately be used as a type, called
2181
2182
an _ object_ .
2182
2183
2183
2184
~~~~
2184
- # trait Drawable { fn draw(); }
2185
+ # trait Drawable { fn draw(&self ); }
2185
2186
fn draw_all(shapes: &[@Drawable]) {
2186
2187
for shapes.each |shape| { shape.draw(); }
2187
2188
}
@@ -2194,14 +2195,14 @@ value to an object:
2194
2195
2195
2196
~~~~
2196
2197
# type Circle = int; type Rectangle = bool;
2197
- # trait Drawable { fn draw(); }
2198
+ # trait Drawable { fn draw(&self ); }
2198
2199
# fn new_circle() -> Circle { 1 }
2199
2200
# fn new_rectangle() -> Rectangle { true }
2200
2201
# fn draw_all(shapes: &[@Drawable]) {}
2201
2202
2202
- impl Circle: Drawable { fn draw() { ... } }
2203
+ impl Circle: Drawable { fn draw(&self ) { ... } }
2203
2204
2204
- impl Rectangle: Drawable { fn draw() { ... } }
2205
+ impl Rectangle: Drawable { fn draw(&self ) { ... } }
2205
2206
2206
2207
let c: @Circle = @new_circle();
2207
2208
let r: @Rectangle = @new_rectangle();
@@ -2218,8 +2219,8 @@ for example, an `@Circle` may not be cast to an `~Drawable`.
2218
2219
2219
2220
~~~
2220
2221
# type Circle = int; type Rectangle = int;
2221
- # trait Drawable { fn draw(); }
2222
- # impl int: Drawable { fn draw() {} }
2222
+ # trait Drawable { fn draw(&self ); }
2223
+ # impl int: Drawable { fn draw(&self ) {} }
2223
2224
# fn new_circle() -> int { 1 }
2224
2225
# fn new_rectangle() -> int { 2 }
2225
2226
// A managed object
@@ -2244,7 +2245,7 @@ The `static` keyword distinguishes static methods from methods that have a `self
2244
2245
2245
2246
~~~~
2246
2247
trait Shape {
2247
- fn area() -> float;
2248
+ fn area(&self ) -> float;
2248
2249
static fn new_shape(area: float) -> Shape;
2249
2250
}
2250
2251
~~~~
@@ -2271,25 +2272,25 @@ Types that implement a trait must also implement its supertraits.
2271
2272
For example, we can define a ` Circle ` trait that only types that also have the ` Shape ` trait can have:
2272
2273
2273
2274
~~~~
2274
- trait Shape { fn area() -> float; }
2275
- trait Circle : Shape { fn radius() -> float; }
2275
+ trait Shape { fn area(&self ) -> float; }
2276
+ trait Circle : Shape { fn radius(&self ) -> float; }
2276
2277
~~~~
2277
2278
2278
2279
Now, implementations of ` Circle ` methods can call ` Shape ` methods:
2279
2280
2280
2281
~~~~
2281
- # trait Shape { fn area() -> float; }
2282
- # trait Circle : Shape { fn radius() -> float; }
2282
+ # trait Shape { fn area(&self ) -> float; }
2283
+ # trait Circle : Shape { fn radius(&self ) -> float; }
2283
2284
# struct Point { x: float, y: float }
2284
2285
# use float::consts::pi;
2285
2286
# use float::sqrt;
2286
2287
# fn square(x: float) -> float { x * x }
2287
2288
struct CircleStruct { center: Point, radius: float }
2288
2289
impl CircleStruct: Circle {
2289
- fn radius() -> float { sqrt(self.area() / pi) }
2290
+ fn radius(&self ) -> float { sqrt(self.area() / pi) }
2290
2291
}
2291
2292
impl CircleStruct: Shape {
2292
- fn area() -> float { pi * square(self.radius) }
2293
+ fn area(&self ) -> float { pi * square(self.radius) }
2293
2294
}
2294
2295
~~~~
2295
2296
@@ -2301,8 +2302,8 @@ methods of the supertrait may be called on values of subtrait-bound type paramet
2301
2302
Refering to the previous example of ` trait Circle : Shape ` :
2302
2303
2303
2304
~~~
2304
- # trait Shape { fn area() -> float; }
2305
- # trait Circle : Shape { fn radius() -> float; }
2305
+ # trait Shape { fn area(&self ) -> float; }
2306
+ # trait Circle : Shape { fn radius(&self ) -> float; }
2306
2307
fn radius_times_area<T: Circle>(c: T) -> float {
2307
2308
// `c` is both a Circle and a Shape
2308
2309
c.radius() * c.area()
@@ -2312,10 +2313,10 @@ fn radius_times_area<T: Circle>(c: T) -> float {
2312
2313
Likewise, supertrait methods may also be called on trait objects.
2313
2314
2314
2315
~~~ {.xfail-test}
2315
- # trait Shape { fn area() -> float; }
2316
- # trait Circle : Shape { fn radius() -> float; }
2317
- # impl int: Shape { fn area() -> float { 0.0 } }
2318
- # impl int: Circle { fn radius() -> float { 0.0 } }
2316
+ # trait Shape { fn area(&self ) -> float; }
2317
+ # trait Circle : Shape { fn radius(&self ) -> float; }
2318
+ # impl int: Shape { fn area(&self ) -> float { 0.0 } }
2319
+ # impl int: Circle { fn radius(&self ) -> float { 0.0 } }
2319
2320
# let mycircle = 0;
2320
2321
2321
2322
let mycircle: Circle = @mycircle as @Circle;
@@ -2385,9 +2386,9 @@ mod farm {
2385
2386
2386
2387
// Note - visibility modifiers on impls currently have no effect
2387
2388
impl Farm {
2388
- priv fn feed_chickens() { ... }
2389
- priv fn feed_cows() { ... }
2390
- fn add_chicken(c: Chicken) { ... }
2389
+ priv fn feed_chickens(&self ) { ... }
2390
+ priv fn feed_cows(&self ) { ... }
2391
+ fn add_chicken(&self, c: Chicken) { ... }
2391
2392
}
2392
2393
2393
2394
pub fn feed_animals(farm: &Farm) {
@@ -2407,7 +2408,7 @@ fn main() {
2407
2408
# enum Human = int;
2408
2409
# fn make_me_a_farm() -> farm::Farm { farm::make_me_a_farm() }
2409
2410
# fn make_me_a_chicken() -> Chicken { 0 }
2410
- # impl Human { fn rest() { } }
2411
+ # impl Human { fn rest(&self ) { } }
2411
2412
~~~
2412
2413
2413
2414
## Crates
0 commit comments