@@ -1551,14 +1551,13 @@ fn contains(v: ~[int], elt: int) -> bool {
1551
1551
1552
1552
## Generic functions
1553
1553
1554
- Throughout this tutorial, we've been defining functions like
1555
- that act only on single data types. It is 2012, and we no longer
1556
- expect to be defining such functions again and again for every type
1557
- they apply to. Thus, Rust allows functions and datatypes to have type
1558
- parameters.
1554
+ Throughout this tutorial, we've been defining functions that act only on
1555
+ single data types. It's a burden to define such functions again and again for
1556
+ every type they apply to. Thus, Rust allows functions and datatypes to have
1557
+ type parameters.
1559
1558
1560
1559
~~~~
1561
- fn map<T, U>(vector: ~ [T], function: fn(T) -> U) -> ~[U] {
1560
+ fn map<T, U>(vector: & [T], function: fn(T) -> U) -> ~[U] {
1562
1561
let mut accumulator = ~[];
1563
1562
for vector.each |element| {
1564
1563
vec::push(accumulator, function(element));
@@ -1577,51 +1576,20 @@ inside them, but you can pass them around.
1577
1576
1578
1577
## Generic datatypes
1579
1578
1580
- Generic ` type ` and ` enum ` declarations follow the same pattern:
1581
-
1582
- ~~~~
1583
- type circular_buf<T> = {start: uint,
1584
- end: uint,
1585
- buf: ~[mut T]};
1586
-
1587
- enum option<T> { some(T), none }
1588
- ~~~~
1589
-
1590
- You can then declare a function to take a ` circular_buf<u8> ` or return
1591
- an ` option<~str> ` , or even an ` option<T> ` if the function itself is
1592
- generic.
1593
-
1594
- The ` option ` type given above exists in the core library and is the
1595
- way Rust programs express the thing that in C would be a nullable
1596
- pointer. The nice part is that you have to explicitly unpack an
1597
- ` option ` type, so accidental null pointer dereferences become
1598
- impossible.
1599
-
1600
- ## Type-inference and generics
1601
-
1602
- Rust's type inferrer works very well with generics, but there are
1603
- programs that just can't be typed.
1579
+ Generic ` type ` , ` struct ` , and ` enum ` declarations follow the same pattern:
1604
1580
1605
1581
~~~~
1606
- let n = option::None;
1607
- # option::iter(n, fn&(&&x:int) {})
1608
- ~~~~
1609
-
1610
- If you never do anything else with ` n ` , the compiler will not be able
1611
- to assign a type to it. (The same goes for ` [] ` , the empty vector.) If
1612
- you really want to have such a statement, you'll have to write it like
1613
- this:
1582
+ struct Stack<T> {
1583
+ elements: ~[mut T]
1584
+ }
1614
1585
1615
- ~~~~
1616
- let n2: Option<int> = option::None;
1617
- // or
1618
- let n = option::None::<int>;
1586
+ enum Maybe<T> {
1587
+ Just(T),
1588
+ Nothing
1589
+ }
1619
1590
~~~~
1620
1591
1621
- Note that, in a value expression, ` < ` already has a meaning as a
1622
- comparison operator, so you'll have to write ` ::<T> ` to explicitly
1623
- give a type to a name that denotes a generic value. Fortunately, this
1624
- is rarely necessary.
1592
+ These declarations produce valid types like ` Stack<u8> ` and ` Maybe<int> ` .
1625
1593
1626
1594
## Kinds
1627
1595
@@ -1661,34 +1629,6 @@ resource type. Rust has several kinds that can be used as type bounds:
1661
1629
> kinds will actually be traits that the compiler has special
1662
1630
> knowledge about.
1663
1631
1664
- ## Generic functions and argument-passing
1665
-
1666
- The previous section mentioned that arguments are passed by pointer or
1667
- by value based on their type. There is one situation in which this is
1668
- difficult. If you try this program:
1669
-
1670
- ~~~~ {.xfail-test}
1671
- fn plus1(x: int) -> int { x + 1 }
1672
- vec::map(~[1, 2, 3], plus1);
1673
- ~~~~
1674
-
1675
- You will get an error message about argument passing styles
1676
- disagreeing. The reason is that generic types are always passed by
1677
- reference, so ` map ` expects a function that takes its argument by
1678
- reference. The ` plus1 ` you defined, however, uses the default,
1679
- efficient way to pass integers, which is by value. To get around this
1680
- issue, you have to explicitly mark the arguments to a function that
1681
- you want to pass to a generic higher-order function as being passed by
1682
- pointer, using the ` && ` sigil:
1683
-
1684
- ~~~~
1685
- fn plus1(&&x: int) -> int { x + 1 }
1686
- vec::map(~[1, 2, 3], plus1);
1687
- ~~~~
1688
-
1689
- > *** Note:*** This is inconvenient, and we are hoping to get rid of
1690
- > this restriction in the future.
1691
-
1692
1632
# Modules and crates
1693
1633
1694
1634
The Rust namespace is divided into modules. Each source file starts
0 commit comments