doc: add information about suffix inference to tutorial and manual.
This commit is contained in:
parent
4dcf84e4f4
commit
1df6ddd08c
22
doc/rust.md
22
doc/rust.md
@ -330,24 +330,32 @@ An _integer literal_ has one of three forms:
|
||||
* A _binary literal_ starts with the character sequence `U+0030` `U+0062`
|
||||
(`0b`) and continues as any mixture binary digits and underscores.
|
||||
|
||||
By default, an integer literal is of type `int`. An integer literal may be
|
||||
followed (immediately, without any spaces) by an _integer suffix_, which
|
||||
changes the type of the literal. There are two kinds of integer literal
|
||||
suffix:
|
||||
An integer literal may be followed (immediately, without any spaces) by an
|
||||
_integer suffix_, which changes the type of the literal. There are two kinds
|
||||
of integer literal suffix:
|
||||
|
||||
* The `u` suffix gives the literal type `uint`.
|
||||
* The `i` and `u` suffixes give the literal type `int` or `uint`,
|
||||
respectively.
|
||||
* Each of the signed and unsigned machine types `u8`, `i8`,
|
||||
`u16`, `i16`, `u32`, `i32`, `u64` and `i64`
|
||||
give the literal the corresponding machine type.
|
||||
|
||||
The type of an _unsuffixed_ integer literal is determined by type inference.
|
||||
If a integer type can be _uniquely_ determined from the surrounding program
|
||||
context, the unsuffixed integer literal has that type. If the program context
|
||||
underconstrains the type, the unsuffixed integer literal's type is `int`; if
|
||||
the program context overconstrains the type, it is considered a static type
|
||||
error.
|
||||
|
||||
Examples of integer literals of various forms:
|
||||
|
||||
~~~~
|
||||
123; // type int
|
||||
123; 0xff00; // type determined by program context;
|
||||
// defaults to int in absence of type
|
||||
// information
|
||||
|
||||
123u; // type uint
|
||||
123_u; // type uint
|
||||
0xff00; // type int
|
||||
0xff_u8; // type u8
|
||||
0b1111_1111_1001_0000_i32; // type i32
|
||||
~~~~
|
||||
|
@ -396,15 +396,58 @@ synonym.
|
||||
|
||||
## Literals
|
||||
|
||||
### Numeric literals
|
||||
|
||||
Integers can be written in decimal (`144`), hexadecimal (`0x90`), and
|
||||
binary (`0b10010000`) base. Without a suffix, an integer literal is
|
||||
considered to be of type `int`. Add a `u` (`144u`) to make it a `uint`
|
||||
instead. Literals of the fixed-size integer types can be created by
|
||||
the literal with the type name (`255u8`, `50i64`, etc).
|
||||
binary (`0b10010000`) base.
|
||||
|
||||
If you write an integer literal without a suffix (`3`, `-500`, etc.),
|
||||
the Rust compiler will try to infer its type based on type annotations
|
||||
and function signatures in the surrounding program. For example, here
|
||||
the type of `x` is inferred to be `u16` because it is passed to a
|
||||
function that takes a `u16` argument:
|
||||
|
||||
~~~~~
|
||||
let x = 3;
|
||||
|
||||
fn identity_u16(n: u16) -> u16 { n }
|
||||
|
||||
identity_u16(x);
|
||||
~~~~
|
||||
|
||||
On the other hand, if the program gives conflicting information about
|
||||
what the type of the unsuffixed literal should be, you'll get an error
|
||||
message.
|
||||
|
||||
~~~~~{.xfail-test}
|
||||
let x = 3;
|
||||
let y: i32 = 3;
|
||||
|
||||
fn identity_u8(n: u8) -> u8 { n }
|
||||
fn identity_u16(n: u16) -> u16 { n }
|
||||
|
||||
identity_u8(x); // after this, `x` is assumed to have type `u8`
|
||||
identity_u16(x); // raises a type error (expected `u16` but found `u8`)
|
||||
identity_u16(y); // raises a type error (expected `u16` but found `i32`)
|
||||
~~~~
|
||||
|
||||
In the absence of any type annotations at all, Rust will assume that
|
||||
an unsuffixed integer literal has type `int`.
|
||||
|
||||
~~~~
|
||||
let n = 50;
|
||||
log(error, n); // n is an int
|
||||
~~~~
|
||||
|
||||
It's also possible to avoid any type ambiguity by writing integer
|
||||
literals with a suffix. The suffixes `i` and `u` are for the types
|
||||
`int` and `uint`, respectively: the literal `-3i` has type `int`,
|
||||
while `127u` has type `uint`. For the fixed-size integer types, just
|
||||
suffix the literal with the type name: `255u8`, `50i64`, etc.
|
||||
|
||||
Note that, in Rust, no implicit conversion between integer types
|
||||
happens. If you are adding one to a variable of type `uint`, you must
|
||||
type `v += 1u`—saying `+= 1` will give you a type error.
|
||||
happens. If you are adding one to a variable of type `uint`, saying
|
||||
`+= 1u8` will give you a type error.
|
||||
|
||||
Floating point numbers are written `0.0`, `1e6`, or `2.1e-4`. Without
|
||||
a suffix, the literal is assumed to be of type `float`. Suffixes `f32`
|
||||
@ -412,6 +455,8 @@ and `f64` can be used to create literals of a specific type. The
|
||||
suffix `f` can be used to write `float` literals without a dot or
|
||||
exponent: `3f`.
|
||||
|
||||
### Other literals
|
||||
|
||||
The nil literal is written just like the type: `()`. The keywords
|
||||
`true` and `false` produce the boolean literals.
|
||||
|
||||
|
22
src/test/compile-fail/tutorial-suffix-inference-test.rs
Normal file
22
src/test/compile-fail/tutorial-suffix-inference-test.rs
Normal file
@ -0,0 +1,22 @@
|
||||
fn main() {
|
||||
let x = 3;
|
||||
let y: i32 = 3;
|
||||
|
||||
fn identity_u8(n: u8) -> u8 { n }
|
||||
fn identity_u16(n: u16) -> u16 { n }
|
||||
|
||||
identity_u8(x); // after this, `x` is assumed to have type `u8`
|
||||
identity_u16(x);
|
||||
//!^ ERROR mismatched types: expected `u16` but found `u8`
|
||||
identity_u16(y);
|
||||
//!^ ERROR mismatched types: expected `u16` but found `i32`
|
||||
|
||||
let a = 3i;
|
||||
|
||||
fn identity_i(n: int) -> int { n }
|
||||
|
||||
identity_i(a); // ok
|
||||
identity_u16(a);
|
||||
//!^ ERROR mismatched types: expected `u16` but found `int`
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user