@@ -918,7 +918,7 @@ match mytup {
918
918
}
919
919
~~~~
920
920
921
- # Functions and methods
921
+ # Functions
922
922
923
923
We've already seen several function definitions. Like all other static
924
924
declarations, such as ` type ` , functions can be declared both at the
@@ -968,52 +968,6 @@ assert 8 == line(5, 3, 1);
968
968
assert () == oops(5, 3, 1);
969
969
~~~~
970
970
971
- Methods are like functions, except that they have an implicit argument
972
- called ` self ` , which has the type that the method's receiver has. The
973
- ` self ` argument is like 'this' in C++. An expression with dot
974
- notation, as in ` my_vec.len() ` , denotes a method
975
- call. Implementations, written with the ` impl ` keyword, can define
976
- methods on most Rust types. As an example, let's define a ` draw `
977
- method on our ` Shape ` enum.
978
-
979
- ~~~
980
- # fn draw_circle(p: Point, f: float) { }
981
- # fn draw_rectangle(p: Point, p: Point) { }
982
- struct Point {
983
- x: float,
984
- y: float
985
- }
986
-
987
- enum Shape {
988
- Circle(Point, float),
989
- Rectangle(Point, Point)
990
- }
991
-
992
- impl Shape {
993
- fn draw() {
994
- match self {
995
- Circle(p, f) => draw_circle(p, f),
996
- Rectangle(p1, p2) => draw_rectangle(p1, p2)
997
- }
998
- }
999
- }
1000
-
1001
- let s = Circle(Point { x: 1f, y: 2f }, 3f);
1002
- s.draw();
1003
- ~~~
1004
-
1005
- This defines an _ implementation_ for ` Shape ` containing a single
1006
- method, ` draw ` . In most respects the ` draw ` method is defined
1007
- like any other function, except for the name ` self ` . ` self `
1008
- is a special value that is automatically in scope inside each method,
1009
- referring to the value being operated on. If we wanted we could add
1010
- additional methods to the same impl, or multiple impls for the same
1011
- type. We'll discuss methods more in the context of [ traits and
1012
- generics] ( #generics ) .
1013
-
1014
- > *** Note:*** In the future, the method definition syntax will change to
1015
- > require declaring the ` self ` type explicitly, as the first argument.
1016
-
1017
971
# The Rust memory model
1018
972
1019
973
At this junction, let's take a detour to explain the concepts involved
@@ -1526,6 +1480,115 @@ if favorite_crayon_name.len() > 5 {
1526
1480
}
1527
1481
~~~
1528
1482
1483
+ # Methods
1484
+
1485
+ Methods are like functions except that they always begin with a special argument,
1486
+ called ` self ` ,
1487
+ which has the type of the method's receiver. The
1488
+ ` self ` argument is like ` this ` in C++ and many other languages.
1489
+ Methods are called with dot notation, as in ` my_vec.len() ` .
1490
+
1491
+ _ Implementations_ , written with the ` impl ` keyword, can define
1492
+ methods on most Rust types, including structs and enums.
1493
+ As an example, let's define a ` draw ` method on our ` Shape ` enum.
1494
+
1495
+ ~~~
1496
+ # fn draw_circle(p: Point, f: float) { }
1497
+ # fn draw_rectangle(p: Point, p: Point) { }
1498
+ struct Point {
1499
+ x: float,
1500
+ y: float
1501
+ }
1502
+
1503
+ enum Shape {
1504
+ Circle(Point, float),
1505
+ Rectangle(Point, Point)
1506
+ }
1507
+
1508
+ impl Shape {
1509
+ fn draw(&self) {
1510
+ match *self {
1511
+ Circle(p, f) => draw_circle(p, f),
1512
+ Rectangle(p1, p2) => draw_rectangle(p1, p2)
1513
+ }
1514
+ }
1515
+ }
1516
+
1517
+ let s = Circle(Point { x: 1f, y: 2f }, 3f);
1518
+ s.draw();
1519
+ ~~~
1520
+
1521
+ This defines an _ implementation_ for ` Shape ` containing a single
1522
+ method, ` draw ` . In most respects the ` draw ` method is defined
1523
+ like any other function, except for the name ` self ` .
1524
+
1525
+ The type of ` self ` is the type on which the method is implemented,
1526
+ or a pointer thereof. As an argument it is written either ` self ` ,
1527
+ ` &self ` , ` @self ` , or ` ~self ` .
1528
+ A caller must in turn have a compatible pointer type to call the method.
1529
+
1530
+ ~~~
1531
+ # fn draw_circle(p: Point, f: float) { }
1532
+ # fn draw_rectangle(p: Point, p: Point) { }
1533
+ # struct Point { x: float, y: float }
1534
+ # enum Shape {
1535
+ # Circle(Point, float),
1536
+ # Rectangle(Point, Point)
1537
+ # }
1538
+ impl Shape {
1539
+ fn draw_borrowed(&self) { ... }
1540
+ fn draw_managed(@self) { ... }
1541
+ fn draw_owned(~self) { ... }
1542
+ fn draw_value(self) { ... }
1543
+ }
1544
+
1545
+ let s = Circle(Point { x: 1f, y: 2f }, 3f);
1546
+
1547
+ (@s).draw_managed();
1548
+ (~s).draw_owned();
1549
+ (&s).draw_borrowed();
1550
+ s.draw_value();
1551
+ ~~~
1552
+
1553
+ Methods typically take a borrowed pointer self type,
1554
+ so the compiler will go to great lengths to convert a callee
1555
+ to a borrowed pointer.
1556
+
1557
+ ~~~
1558
+ # fn draw_circle(p: Point, f: float) { }
1559
+ # fn draw_rectangle(p: Point, p: Point) { }
1560
+ # struct Point { x: float, y: float }
1561
+ # enum Shape {
1562
+ # Circle(Point, float),
1563
+ # Rectangle(Point, Point)
1564
+ # }
1565
+ # impl Shape {
1566
+ # fn draw_borrowed(&self) { ... }
1567
+ # fn draw_managed(@self) { ... }
1568
+ # fn draw_owned(~self) { ... }
1569
+ # fn draw_value(self) { ... }
1570
+ # }
1571
+ # let s = Circle(Point { x: 1f, y: 2f }, 3f);
1572
+ // As with typical function arguments, managed and unique pointers
1573
+ // are automatically converted to borrowed pointers
1574
+
1575
+ (@s).draw_borrowed();
1576
+ (~s).draw_borrowed();
1577
+
1578
+ // Unlike typical function arguments, the self value will
1579
+ // automatically be referenced ...
1580
+ s.draw_borrowed();
1581
+
1582
+ // ... and dereferenced
1583
+ (& &s).draw_borrowed();
1584
+
1585
+ // ... and dereferenced, and borrowed, and
1586
+ (&@~s).draw_borrowed();
1587
+ ~~~
1588
+
1589
+ We'll discuss implementations more in the context of [ traits and
1590
+ generics] ( #generics ) .
1591
+
1529
1592
# Closures
1530
1593
1531
1594
Named functions, like those we've seen so far, may not refer to local
0 commit comments