about summary refs log tree commit diff
path: root/src/doc/complement-cheatsheet.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc/complement-cheatsheet.md')
-rw-r--r--src/doc/complement-cheatsheet.md214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/doc/complement-cheatsheet.md b/src/doc/complement-cheatsheet.md
new file mode 100644
index 00000000000..a92980d5e70
--- /dev/null
+++ b/src/doc/complement-cheatsheet.md
@@ -0,0 +1,214 @@
+% Rust Cheatsheet
+
+# How do I convert *X* to *Y*?
+
+**Int to string**
+
+Use [`ToStr`](http://static.rust-lang.org/doc/master/std/to_str/trait.ToStr.html).
+
+~~~
+let x: int = 42;
+let y: ~str = x.to_str();
+~~~
+
+**String to int**
+
+Use [`FromStr`](http://static.rust-lang.org/doc/master/std/from_str/trait.FromStr.html), and its helper function, [`from_str`](http://static.rust-lang.org/doc/master/std/from_str/fn.from_str.html).
+
+~~~
+let x: Option<int> = from_str("42");
+let y: int = x.unwrap();
+~~~
+
+**Int to string, in non-base-10**
+
+Use [`ToStrRadix`](http://static.rust-lang.org/doc/master/std/num/trait.ToStrRadix.html).
+
+~~~
+use std::num::ToStrRadix;
+
+let x: int = 42;
+let y: ~str = x.to_str_radix(16);
+~~~
+
+**String to int, in non-base-10**
+
+Use [`FromStrRadix`](http://static.rust-lang.org/doc/master/std/num/trait.FromStrRadix.html), and its helper function, [`from_str_radix`](http://static.rust-lang.org/doc/master/std/num/fn.from_str_radix.html).
+
+~~~
+use std::num::from_str_radix;
+
+let x: Option<i64> = from_str_radix("deadbeef", 16);
+let y: i64 = x.unwrap();
+~~~
+
+# File operations
+
+## How do I read from a file?
+
+Use [`File::open`](http://static.rust-lang.org/doc/master/std/io/fs/struct.File.html#method.open) to create a [`File`](http://static.rust-lang.org/doc/master/std/io/fs/struct.File.html) struct, which implements the [`Reader`](http://static.rust-lang.org/doc/master/std/io/trait.Reader.html) trait.
+
+~~~ {.ignore}
+use std::path::Path;
+use std::io::fs::File;
+
+let path : Path   = Path::new("Doc-FAQ-Cheatsheet.md");
+let on_error      = || fail!("open of {:?} failed", path);
+let reader : File = File::open(&path).unwrap_or_else(on_error);
+~~~
+
+## How do I iterate over the lines in a file?
+
+Use the [`lines`](http://static.rust-lang.org/doc/master/std/io/trait.Buffer.html#method.lines) method on a [`BufferedReader`](http://static.rust-lang.org/doc/master/std/io/buffered/struct.BufferedReader.html).
+
+~~~
+use std::io::BufferedReader;
+# use std::io::MemReader;
+
+# let reader = MemReader::new(~[]);
+
+let mut reader = BufferedReader::new(reader);
+for line in reader.lines() {
+    print!("line: {}", line);
+}
+~~~
+
+# String operations
+
+## How do I search for a substring?
+
+Use the [`find_str`](http://static.rust-lang.org/doc/master/std/str/trait.StrSlice.html#tymethod.find_str) method.
+
+~~~
+let str = "Hello, this is some random string";
+let index: Option<uint> = str.find_str("rand");
+~~~
+
+# Containers
+
+## How do I get the length of a vector?
+
+The [`Container`](http://static.rust-lang.org/doc/master/std/container/trait.Container.html) trait provides the `len` method.
+
+~~~
+let u: ~[u32] = ~[0, 1, 2];
+let v: &[u32] = &[0, 1, 2, 3];
+let w: [u32, .. 5] = [0, 1, 2, 3, 4];
+
+println!("u: {}, v: {}, w: {}", u.len(), v.len(), w.len()); // 3, 4, 5
+~~~
+
+## How do I iterate over a vector?
+
+Use the [`iter`](http://static.rust-lang.org/doc/master/std/vec/trait.ImmutableVector.html#tymethod.iter) method.
+
+~~~
+let values: ~[int] = ~[1, 2, 3, 4, 5];
+for value in values.iter() {  // value: &int
+    println!("{}", *value);
+}
+~~~
+
+(See also [`mut_iter`](http://static.rust-lang.org/doc/master/std/vec/trait.MutableVector.html#tymethod.mut_iter) which yields `&mut int` and [`move_iter`](http://static.rust-lang.org/doc/master/std/vec/trait.OwnedVector.html#tymethod.move_iter) which yields `int` while consuming the `values` vector.)
+
+# Type system
+
+## How do I store a function in a struct?
+
+~~~
+struct Foo {
+    myfunc: fn(int, uint) -> i32
+}
+
+struct FooClosure<'a> {
+    myfunc: 'a |int, uint| -> i32
+}
+
+fn a(a: int, b: uint) -> i32 {
+    (a as uint + b) as i32
+}
+
+fn main() {
+    let f = Foo { myfunc: a };
+    let g = FooClosure { myfunc: |a, b|  { (a - b as int) as i32 } };
+    println!("{}", (f.myfunc)(1, 2));
+    println!("{}", (g.myfunc)(3, 4));
+}
+~~~
+
+Note that the parenthesis surrounding `f.myfunc` are necessary: they are how Rust disambiguates field lookup and method call. The `'a` on `FooClosure` is the lifetime of the closure's environment pointer.
+
+## How do I express phantom types?
+
+[Phantom types](http://www.haskell.org/haskellwiki/Phantom_type) are those that cannot be constructed at compile time. To express these in Rust, zero-variant `enum`s can be used:
+
+~~~
+enum Open {}
+enum Closed {}
+~~~
+
+Phantom types are useful for enforcing state at compile time. For example:
+
+~~~
+struct Door<State>(~str);
+
+struct Open;
+struct Closed;
+
+fn close(Door(name): Door<Open>) -> Door<Closed> {
+    Door::<Closed>(name)
+}
+
+fn open(Door(name): Door<Closed>) -> Door<Open> {
+    Door::<Open>(name)
+}
+
+let _ = close(Door::<Open>(~"front"));
+~~~
+
+Attempting to close a closed door is prevented statically:
+
+~~~ {.ignore}
+let _ = close(Door::<Closed>(~"front")); // error: mismatched types: expected `main::Door<main::Open>` but found `main::Door<main::Closed>`
+~~~
+
+# FFI (Foreign Function Interface)
+
+## C function signature conversions
+
+Description            C signature                                    Equivalent Rust signature
+---------------------- ---------------------------------------------- ------------------------------------------
+no parameters          `void foo(void);`                              `fn foo();`
+return value           `int foo(void);`                               `fn foo() -> c_int;`
+function parameters    `void foo(int x, int y);`                      `fn foo(x: int, y: int);`
+in-out pointers        `void foo(const int* in_ptr, int* out_ptr);`   `fn foo(in_ptr: *c_int, out_ptr: *mut c_int);`
+
+Note: The Rust signatures should be wrapped in an `extern "ABI" { ... }` block.
+
+### Representing opaque handles
+
+You might see things like this in C APIs:
+
+~~~ {.notrust}
+typedef struct Window Window;
+Window* createWindow(int width, int height);
+~~~
+
+You can use a zero-element `enum` ([phantom type](#how-do-i-express-phantom-types)) to represent the opaque object handle. The FFI would look like this:
+
+~~~ {.ignore}
+enum Window {}
+extern "C" {
+    fn createWindow(width: c_int, height: c_int) -> *Window;
+}
+~~~
+
+Using a phantom type ensures that the handles cannot be (safely) constructed in client code.
+
+# Contributing to this page
+
+For small examples, have full type annotations, as much as is reasonable, to keep it clear what, exactly, everything is doing. Try to link to the API docs, as well.
+
+Similar documents for other programming languages:
+
+  * [http://pleac.sourceforge.net/](http://pleac.sourceforge.net)