Skip to content

Commit 0617708

Browse files
committed
tutorial: Move method discussion after closures, before generics
/cc: rust-lang#4217
1 parent cad30a2 commit 0617708

File tree

1 file changed

+136
-139
lines changed

1 file changed

+136
-139
lines changed

doc/tutorial.md

Lines changed: 136 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,145 +1480,6 @@ if favorite_crayon_name.len() > 5 {
14801480
}
14811481
~~~
14821482

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-
Implementations may also define _static_ methods,
1590-
which don't have an explicit `self` argument.
1591-
The `static` keyword distinguishes static methods from methods that have a `self`:
1592-
1593-
~~~~ {.xfail-test}
1594-
impl Circle {
1595-
fn area(&self) -> float { ... }
1596-
static fn new(area: float) -> Circle { ... }
1597-
}
1598-
~~~~
1599-
1600-
> ***Note***: In the future the `static` keyword will be removed and static methods
1601-
> will be distinguished solely by the presence or absence of the `self` argument.
1602-
> In the current langugage instance methods may also be declared without an explicit
1603-
> `self` argument, in which case `self` is an implicit reference.
1604-
> That form of method is deprecated.
1605-
1606-
Constructors are one common application for static methods, as in `new` above.
1607-
To call a static method, you have to prefix it with the type name and a double colon:
1608-
1609-
~~~~
1610-
# use float::consts::pi;
1611-
# use float::sqrt;
1612-
struct Circle { radius: float }
1613-
impl Circle {
1614-
static fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }
1615-
}
1616-
let c = Circle::new(42.5);
1617-
~~~~
1618-
1619-
We'll discuss implementations more in the context of [traits and
1620-
generics](#generics).
1621-
16221483
# Closures
16231484

16241485
Named functions, like those we've seen so far, may not refer to local
@@ -1886,6 +1747,142 @@ fn contains(v: &[int], elt: int) -> bool {
18861747
> the keywords `break`, `loop`, and `return` work, in varying degree,
18871748
> with `while`, `loop`, `do`, and `for` constructs.
18881749
1750+
# Methods
1751+
1752+
Methods are like functions except that they always begin with a special argument,
1753+
called `self`,
1754+
which has the type of the method's receiver. The
1755+
`self` argument is like `this` in C++ and many other languages.
1756+
Methods are called with dot notation, as in `my_vec.len()`.
1757+
1758+
_Implementations_, written with the `impl` keyword, can define
1759+
methods on most Rust types, including structs and enums.
1760+
As an example, let's define a `draw` method on our `Shape` enum.
1761+
1762+
~~~
1763+
# fn draw_circle(p: Point, f: float) { }
1764+
# fn draw_rectangle(p: Point, p: Point) { }
1765+
struct Point {
1766+
x: float,
1767+
y: float
1768+
}
1769+
1770+
enum Shape {
1771+
Circle(Point, float),
1772+
Rectangle(Point, Point)
1773+
}
1774+
1775+
impl Shape {
1776+
fn draw(&self) {
1777+
match *self {
1778+
Circle(p, f) => draw_circle(p, f),
1779+
Rectangle(p1, p2) => draw_rectangle(p1, p2)
1780+
}
1781+
}
1782+
}
1783+
1784+
let s = Circle(Point { x: 1f, y: 2f }, 3f);
1785+
s.draw();
1786+
~~~
1787+
1788+
This defines an _implementation_ for `Shape` containing a single
1789+
method, `draw`. In most respects the `draw` method is defined
1790+
like any other function, except for the name `self`.
1791+
1792+
The type of `self` is the type on which the method is implemented,
1793+
or a pointer thereof. As an argument it is written either `self`,
1794+
`&self`, `@self`, or `~self`.
1795+
A caller must in turn have a compatible pointer type to call the method.
1796+
1797+
~~~
1798+
# fn draw_circle(p: Point, f: float) { }
1799+
# fn draw_rectangle(p: Point, p: Point) { }
1800+
# struct Point { x: float, y: float }
1801+
# enum Shape {
1802+
# Circle(Point, float),
1803+
# Rectangle(Point, Point)
1804+
# }
1805+
impl Shape {
1806+
fn draw_borrowed(&self) { ... }
1807+
fn draw_managed(@self) { ... }
1808+
fn draw_owned(~self) { ... }
1809+
fn draw_value(self) { ... }
1810+
}
1811+
1812+
let s = Circle(Point { x: 1f, y: 2f }, 3f);
1813+
1814+
(@s).draw_managed();
1815+
(~s).draw_owned();
1816+
(&s).draw_borrowed();
1817+
s.draw_value();
1818+
~~~
1819+
1820+
Methods typically take a borrowed pointer self type,
1821+
so the compiler will go to great lengths to convert a callee
1822+
to a borrowed pointer.
1823+
1824+
~~~
1825+
# fn draw_circle(p: Point, f: float) { }
1826+
# fn draw_rectangle(p: Point, p: Point) { }
1827+
# struct Point { x: float, y: float }
1828+
# enum Shape {
1829+
# Circle(Point, float),
1830+
# Rectangle(Point, Point)
1831+
# }
1832+
# impl Shape {
1833+
# fn draw_borrowed(&self) { ... }
1834+
# fn draw_managed(@self) { ... }
1835+
# fn draw_owned(~self) { ... }
1836+
# fn draw_value(self) { ... }
1837+
# }
1838+
# let s = Circle(Point { x: 1f, y: 2f }, 3f);
1839+
// As with typical function arguments, managed and unique pointers
1840+
// are automatically converted to borrowed pointers
1841+
1842+
(@s).draw_borrowed();
1843+
(~s).draw_borrowed();
1844+
1845+
// Unlike typical function arguments, the self value will
1846+
// automatically be referenced ...
1847+
s.draw_borrowed();
1848+
1849+
// ... and dereferenced
1850+
(& &s).draw_borrowed();
1851+
1852+
// ... and dereferenced, and borrowed, and
1853+
(&@~s).draw_borrowed();
1854+
~~~
1855+
1856+
Implementations may also define _static_ methods,
1857+
which don't have an explicit `self` argument.
1858+
The `static` keyword distinguishes static methods from methods that have a `self`:
1859+
1860+
~~~~ {.xfail-test}
1861+
impl Circle {
1862+
fn area(&self) -> float { ... }
1863+
static fn new(area: float) -> Circle { ... }
1864+
}
1865+
~~~~
1866+
1867+
> ***Note***: In the future the `static` keyword will be removed and static methods
1868+
> will be distinguished solely by the presence or absence of the `self` argument.
1869+
> In the current langugage instance methods may also be declared without an explicit
1870+
> `self` argument, in which case `self` is an implicit reference.
1871+
> That form of method is deprecated.
1872+
1873+
Constructors are one common application for static methods, as in `new` above.
1874+
To call a static method, you have to prefix it with the type name and a double colon:
1875+
1876+
~~~~
1877+
# use float::consts::pi;
1878+
# use float::sqrt;
1879+
struct Circle { radius: float }
1880+
impl Circle {
1881+
static fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }
1882+
}
1883+
let c = Circle::new(42.5);
1884+
~~~~
1885+
18891886
# Generics
18901887

18911888
Throughout this tutorial, we've been defining functions that act only

0 commit comments

Comments
 (0)