https://doc.rust-lang.org/rust-by-example/primitives.html
Scalar Values | ||
---|---|---|
Signed Integers | i8 , i16 , i32 , i64 , i128 and isize (architecture pointer size) |
let x: i32 = -42; |
Unsigned Integers | u8 , u16 , u32 , u64 , u128 and usize (architecture pointer size) |
let x: u32 = 42; |
Floating Point | f32 , f64 |
let y: f64 = 1.0; |
Unicode (4 bytes) | char |
let x: char = 'x'; |
String | str |
let x: &'static str = "Hello there."; |
Boolean | bool |
let z: bool = false; |
Unit | () (only possible value is an empty tuple) |
() |
Compound Values | ||
---|---|---|
Array | [T, len] |
let a: [i32; 3] = [1, 2, 3]; |
Tuple | (T1, T2, ...) |
let x: (i32, &str) = (1, "hello"); |
Integers can, alternatively, be expressed using hexadecimal, octal or binary notation using these prefixes respectively: 0x
, 0o
or 0b
. 0x80
or 0b0011
as examples.
Arrays are created using brackets []
, and their length, which is known at compile time, is part of their type signature [T; length]
.
https://rustwasm.github.io/docs/wasm-bindgen/reference/types.html
Rust/bindgen type | T param |
&T param |
&mut T param |
T return |
Option<&T> param |
Option<T> return |
JS Type |
---|---|---|---|---|---|---|---|
JsValue |
✅ | ✅ | ❌ | ✅ | ❌ | ❌ | any |
Box<[JsValue]> |
✅ | ❌ | ❌ | ✅ | ✅ | ✅ | any[] |
*const T / *mut T |
✅ | ❌ | ❌ | ✅ | ❌ | ❌ | number |
(Un)Signed / Float | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | number |
bool |
✅ | ❌ | ❌ | ✅ | ✅ | ✅ | boolean |
char |
✅ | ❌ | ❌ | ✅ | ❌ | ❌ | string |
str |
❌ | ✅ | ❌ | ❌ | ❌ | ❌ | string |
String |
✅ | ❌ | ❌ | ✅ | ✅ | ✅ | string |
Number Slice ([u16] ) |
❌ | ✅ | ✅ | ❌ | ❌ | ❌ | TypedArray |
Boxed Number Slice | ✅ | ❌ | ❌ | ✅ | ✅ | ✅ | TypedArray |
Result<T, JsValue> † |
❌ | ❌ | ❌ | ❌ | ❌ | ❌ | T / Error |
† : The Result
type can be returned from functions exported to JS as well as closures in Rust. Only Result<T, JsValue>
is supported where T
can be converted to JS. Whenever Ok(val)
is encountered it's converted to JS and handed off, and whenever Err(error)
is encountered an exception is thrown in JS with error.
- Variable bindings are immutable by default, but this can be overridden using the
mut
modifier.
let _immutable_binding = 1;
let mut mutable_binding = 1;
- Rust provides no implicit type conversion (coercion) between primitive types. But, explicit type conversion (casting) can be performed using the
as
keyword.
let decimal = 65.4321_f32;
let integer = decimal as u8;
let character = integer as char;
-
When casting any value to an unsigned type, T, T::MAX + 1 is added or subtracted until the value fits into the new type. Under the hood, the first 8 least significant bits (LSB) are kept, while the rest towards the most significant bit (MSB) get truncated.
-
Numeric literals can be type annotated by adding the type as a suffix. As an example, to specify that the literal 42 should have the type
i32
, write42i32
. The type of unsuffixed numeric literals will depend on how they are used. If no constraint exists, the compiler will usei32
for integers, andf64
for floating-point numbers. -
The type inference engine is pretty smart. It does more than looking at the type of the value expression during an initialization. It also looks at how the variable is used afterwards to infer its type.
-
Slices are similar to arrays, but their length is not known at compile time. Instead, a slice is a two-word object; the first word is a pointer to the data, the second word the length of the slice. Slices can point to a section of an array. They are of the form
[starting_index..ending_index]
.starting_index
is the first position in the slice.ending_index
is one more than the last position in the slice.
// Given
let xs: [i32; 5] = [1, 2, 3, 4, 5];
// The Slice
&xs[1 .. 3];
let
can be used to bind the members (spread) of a tuple to variables.
fn reverse(pair: (i32, bool)) -> (bool, i32) {
let (int_param, bool_param) = pair;
(bool_param, int_param)
}
-
There are three types of structures that can be created using the
struct
keyword:- Tuple structs, which are, basically, named tuples.
struct Pair(i32, f32);
- Unit structs, which are field-less, are useful for generics.
struct Unit;
- The classic C structs
struct Point { x: f32, y: f32, }
-
The
enum
keyword allows the creation of a type which may be one of a few different variants. Any variant which is valid as astruct
is also valid in anenum
.
enum WebEvent {
// An `enum` variant may either be `unit-like`,
PageLoad,
PageUnload,
// like tuple structs,
KeyPress(char),
Paste(String),
// or c-like structures.
Click { x: i64, y: i64 },
}
enum
can also be used as C-like enums.
// enum with implicit discriminator (starts at 0)
enum Number {
Zero,
One,
Two,
}
- The
use
declaration can be used so manual scoping isn't needed
// Explicitly `use` each name so they are available without
// manual scoping.
use crate::Status::{Poor, Rich};
// Automatically `use` each name inside `Work`.
use crate::Work::*;