Skip to content

Commit f5bb5a7

Browse files
committed
---
yaml --- r: 128684 b: refs/heads/try c: e55e27d h: refs/heads/master v: v3
1 parent fed406a commit f5bb5a7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1497
-422
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 07d86b46a949a94223da714e35b343243e4ecce4
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a86d9ad15e339ab343a12513f9c90556f677b9ca
5-
refs/heads/try: 6b9a202899f19f89333c0ac0b8f466a99cd4a722
5+
refs/heads/try: e55e27db1e92b682a2ce64f695c5d3241db80989
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/configure

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -557,13 +557,21 @@ fi
557557

558558
if [ ! -z "$CFG_ENABLE_LOCAL_RUST" ]
559559
then
560-
if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} ]
560+
system_rustc=$(which rustc)
561+
if [ -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} ]
561562
then
562-
err "no local rust to use"
563+
: # everything already configured
564+
elif [ -n "$system_rustc" ]
565+
then
566+
# we assume that rustc is in a /bin directory
567+
CFG_LOCAL_RUST_ROOT=${system_rustc%/bin/rustc}
563568
else
564-
LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} --version`
565-
step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
569+
err "no local rust to use"
566570
fi
571+
572+
LRV=`${CFG_LOCAL_RUST_ROOT}/bin/rustc${BIN_SUF} --version`
573+
step_msg "using rustc at: ${CFG_LOCAL_RUST_ROOT} with version: $LRV"
574+
putvar CFG_LOCAL_RUST_ROOT
567575
fi
568576

569577
# Force freebsd to build with clang; gcc doesn't like us there

branches/try/src/doc/guide.md

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,86 @@ building our guessing game, but we need to know how to do one last thing first:
14321432
get input from the keyboard. You can't have a guessing game without the ability
14331433
to guess!
14341434

1435+
# Strings
1436+
1437+
Strings are an important concept for any programmer to master. Rust's string
1438+
handling system is a bit different than in other languages, due to its systems
1439+
focus. Any time you have a data structure of variable size, things can get
1440+
tricky, and strings are a re-sizable data structure. That said, Rust's strings
1441+
also work differently than in some other systems languages, such as C.
1442+
1443+
Let's dig into the details. A **string** is a sequence of unicode scalar values
1444+
encoded as a stream of UTF-8 bytes. All strings are guaranteed to be
1445+
validly-encoded UTF-8 sequences. Additionally, strings are not null-terminated
1446+
and can contain null bytes.
1447+
1448+
Rust has two main types of strings: `&str` and `String`.
1449+
1450+
The first kind is a `&str`. This is pronounced a 'string slice.' String literals
1451+
are of the type `&str`:
1452+
1453+
```{rust}
1454+
let string = "Hello there.";
1455+
```
1456+
1457+
This string is statically allocated, meaning that it's saved inside our
1458+
compiled program, and exists for the entire duration it runs. The `string`
1459+
binding is a reference to this statically allocated string. String slices
1460+
have a fixed size, and cannot be mutated.
1461+
1462+
A `String`, on the other hand, is an in-memory string. This string is
1463+
growable, and is also guaranteed to be UTF-8.
1464+
1465+
```{rust}
1466+
let mut s = "Hello".to_string();
1467+
println!("{}", s);
1468+
1469+
s.push_str(", world.");
1470+
println!("{}", s);
1471+
```
1472+
1473+
You can coerce a `String` into a `&str` with the `as_slice()` method:
1474+
1475+
```{rust}
1476+
fn takes_slice(slice: &str) {
1477+
println!("Got: {}", slice);
1478+
}
1479+
1480+
fn main() {
1481+
let s = "Hello".to_string();
1482+
takes_slice(s.as_slice());
1483+
}
1484+
```
1485+
1486+
To compare a String to a constant string, prefer `as_slice()`...
1487+
1488+
```{rust}
1489+
fn compare(string: String) {
1490+
if string.as_slice() == "Hello" {
1491+
println!("yes");
1492+
}
1493+
}
1494+
```
1495+
1496+
... over `to_string()`:
1497+
1498+
```{rust}
1499+
fn compare(string: String) {
1500+
if string == "Hello".to_string() {
1501+
println!("yes");
1502+
}
1503+
}
1504+
```
1505+
1506+
Converting a `String` to a `&str` is cheap, but converting the `&str` to a
1507+
`String` involves allocating memory. No reason to do that unless you have to!
1508+
1509+
That's the basics of strings in Rust! They're probably a bit more complicated
1510+
than you are used to, if you come from a scripting language, but when the
1511+
low-level details matter, they really matter. Just remember that `String`s
1512+
allocate memory and control their data, while `&str`s are a reference to
1513+
another string, and you'll be all set.
1514+
14351515
# Standard Input
14361516

14371517
Getting input from the keyboard is pretty easy, but uses some things
@@ -3614,6 +3694,94 @@ guide](http://doc.rust-lang.org/guide-pointers.html#rc-and-arc).
36143694

36153695
# Patterns
36163696

3697+
# Method Syntax
3698+
3699+
Functions are great, but if you want to call a bunch of them on some data, it
3700+
can be awkward. Consider this code:
3701+
3702+
```{rust,ignore}
3703+
baz(bar(foo(x)));
3704+
```
3705+
3706+
We would read this left-to right, and so we see 'baz bar foo.' But this isn't the
3707+
order that the functions would get called in, that's inside-out: 'foo bar baz.'
3708+
Wouldn't it be nice if we could do this instead?
3709+
3710+
```{rust,ignore}
3711+
x.foo().bar().baz();
3712+
```
3713+
3714+
Luckily, as you may have guessed with the leading question, you can! Rust provides
3715+
the ability to use this **method call syntax** via the `impl` keyword.
3716+
3717+
Here's how it works:
3718+
3719+
```
3720+
struct Circle {
3721+
x: f64,
3722+
y: f64,
3723+
radius: f64,
3724+
}
3725+
3726+
impl Circle {
3727+
fn area(&self) -> f64 {
3728+
std::f64::consts::PI * (self.radius * self.radius)
3729+
}
3730+
}
3731+
3732+
fn main() {
3733+
let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
3734+
println!("{}", c.area());
3735+
}
3736+
```
3737+
3738+
This will print `12.566371`.
3739+
3740+
We've made a struct that represents a circle. We then write an `impl` block,
3741+
and inside it, define a method, `area`. Methods take a special first
3742+
parameter, `&self`. There are three variants: `self`, `&self`, and `&mut self`.
3743+
You can think of this first parameter as being the `x` in `x.foo()`. The three
3744+
variants correspond to the three kinds of thing `x` could be: `self` if it's
3745+
just a value on the stack, `&self` if it's a reference, and `&mut self` if it's
3746+
a mutable reference. We should default to using `&self`, as it's the most
3747+
common.
3748+
3749+
Finally, as you may remember, the value of the area of a circle is `π*r²`.
3750+
Because we took the `&self` parameter to `area`, we can use it just like any
3751+
other parameter. Because we know it's a `Circle`, we can access the `radius`
3752+
just like we would with any other struct. An import of π and some
3753+
multiplications later, and we have our area.
3754+
3755+
You can also define methods that do not take a `self` parameter. Here's a
3756+
pattern that's very common in Rust code:
3757+
3758+
```
3759+
struct Circle {
3760+
x: f64,
3761+
y: f64,
3762+
radius: f64,
3763+
}
3764+
3765+
impl Circle {
3766+
fn new(x: f64, y: f64, radius: f64) -> Circle {
3767+
Circle {
3768+
x: x,
3769+
y: y,
3770+
radius: radius,
3771+
}
3772+
}
3773+
}
3774+
3775+
fn main() {
3776+
let c = Circle::new(0.0, 0.0, 2.0);
3777+
}
3778+
```
3779+
3780+
This **static method** builds a new `Circle` for us. Note that static methods
3781+
are called with the `Struct::method()` syntax, rather than the `ref.method()`
3782+
syntax.
3783+
3784+
36173785
# Closures
36183786

36193787
So far, we've made lots of functions in Rust. But we've given them all names.
@@ -4318,6 +4486,152 @@ the same function, so our binary is a little bit larger.
43184486

43194487
# Tasks
43204488

4489+
Concurrency and parallelism are topics that are of increasing interest to a
4490+
broad subsection of software developers. Modern computers are often multi-core,
4491+
to the point that even embedded devices like cell phones have more than one
4492+
processor. Rust's semantics lend themselves very nicely to solving a number of
4493+
issues that programmers have with concurrency. Many concurrency errors that are
4494+
runtime errors in other languages are compile-time errors in Rust.
4495+
4496+
Rust's concurrency primitive is called a **task**. Tasks are lightweight, and
4497+
do not share memory in an unsafe manner, preferring message passing to
4498+
communicate. It's worth noting that tasks are implemented as a library, and
4499+
not part of the language. This means that in the future, other concurrency
4500+
libraries can be written for Rust to help in specific scenarios. Here's an
4501+
example of creating a task:
4502+
4503+
```{rust}
4504+
spawn(proc() {
4505+
println!("Hello from a task!");
4506+
});
4507+
```
4508+
4509+
The `spawn` function takes a proc as an argument, and runs that proc in a new
4510+
task. A proc takes ownership of its entire environment, and so any variables
4511+
that you use inside the proc will not be usable afterward:
4512+
4513+
```{rust,ignore}
4514+
let mut x = vec![1i, 2i, 3i];
4515+
4516+
spawn(proc() {
4517+
println!("The value of x[0] is: {}", x[0]);
4518+
});
4519+
4520+
println!("The value of x[0] is: {}", x[0]); // error: use of moved value: `x`
4521+
```
4522+
4523+
`x` is now owned by the proc, and so we can't use it anymore. Many other
4524+
languages would let us do this, but it's not safe to do so. Rust's type system
4525+
catches the error.
4526+
4527+
If tasks were only able to capture these values, they wouldn't be very useful.
4528+
Luckily, tasks can communicate with each other through **channel**s. Channels
4529+
work like this:
4530+
4531+
```{rust}
4532+
let (tx, rx) = channel();
4533+
4534+
spawn(proc() {
4535+
tx.send("Hello from a task!".to_string());
4536+
});
4537+
4538+
let message = rx.recv();
4539+
println!("{}", message);
4540+
```
4541+
4542+
The `channel()` function returns two endpoints: a `Receiver<T>` and a
4543+
`Sender<T>`. You can use the `.send()` method on the `Sender<T>` end, and
4544+
receive the message on the `Receiver<T>` side with the `recv()` method. This
4545+
method blocks until it gets a message. There's a similar method, `.try_recv()`,
4546+
which returns an `Option<T>` and does not block.
4547+
4548+
If you want to send messages to the task as well, create two channels!
4549+
4550+
```{rust}
4551+
let (tx1, rx1) = channel();
4552+
let (tx2, rx2) = channel();
4553+
4554+
spawn(proc() {
4555+
tx1.send("Hello from a task!".to_string());
4556+
let message = rx2.recv();
4557+
println!("{}", message);
4558+
});
4559+
4560+
let message = rx1.recv();
4561+
println!("{}", message);
4562+
4563+
tx2.send("Goodbye from main!".to_string());
4564+
```
4565+
4566+
The proc has one sending end and one receiving end, and the main task has one
4567+
of each as well. Now they can talk back and forth in whatever way they wish.
4568+
4569+
Notice as well that because `Sender` and `Receiver` are generic, while you can
4570+
pass any kind of information through the channel, the ends are strongly typed.
4571+
If you try to pass a string, and then an integer, Rust will complain.
4572+
4573+
## Futures
4574+
4575+
With these basic primitives, many different concurrency patterns can be
4576+
developed. Rust includes some of these types in its standard library. For
4577+
example, if you wish to compute some value in the background, `Future` is
4578+
a useful thing to use:
4579+
4580+
```{rust}
4581+
use std::sync::Future;
4582+
4583+
let mut delayed_value = Future::spawn(proc() {
4584+
// just return anything for examples' sake
4585+
4586+
12345i
4587+
});
4588+
println!("value = {}", delayed_value.get());
4589+
```
4590+
4591+
Calling `Future::spawn` works just like `spawn()`: it takes a proc. In this
4592+
case, though, you don't need to mess with the channel: just have the proc
4593+
return the value.
4594+
4595+
`Future::spawn` will return a value which we can bind with `let`. It needs
4596+
to be mutable, because once the value is computed, it saves a copy of the
4597+
value, and if it were immutable, it couldn't update itself.
4598+
4599+
The proc will go on processing in the background, and when we need the final
4600+
value, we can call `get()` on it. This will block until the result is done,
4601+
but if it's finished computing in the background, we'll just get the value
4602+
immediately.
4603+
4604+
## Success and failure
4605+
4606+
Tasks don't always succeed, they can also fail. A task that wishes to fail
4607+
can call the `fail!` macro, passing a message:
4608+
4609+
```{rust}
4610+
spawn(proc() {
4611+
fail!("Nope.");
4612+
});
4613+
```
4614+
4615+
If a task fails, it is not possible for it to recover. However, it can
4616+
notify other tasks that it has failed. We can do this with `task::try`:
4617+
4618+
```{rust}
4619+
use std::task;
4620+
use std::rand;
4621+
4622+
let result = task::try(proc() {
4623+
if rand::random() {
4624+
println!("OK");
4625+
} else {
4626+
fail!("oops!");
4627+
}
4628+
});
4629+
```
4630+
4631+
This task will randomly fail or succeed. `task::try` returns a `Result`
4632+
type, so we can handle the response like any other computation that may
4633+
fail.
4634+
43214635
# Macros
43224636

43234637
# Unsafe

0 commit comments

Comments
 (0)