8

I'm new to Rust. I understand that Rust predicts the type of bindings at compile time. The below code compiles and runs.

fn main() {
    let mut numbers = Vec::new();
    numbers.push(1);
}

What is the default type of the numbers vector?

user51
  • 8,843
  • 21
  • 79
  • 158
  • 3
    [No, it doesn't](https://play.rust-lang.org/?gist=e4a658f8f1f93d753c310f9aa98b11eb&version=stable). – DK. Apr 17 '18 at 03:52
  • I'm very interested to know what compiler you're using and/or what you define as "compiles and runs". – MutantOctopus Apr 17 '18 at 04:08
  • I meant `rustc` and I'm using cargo. – user51 Apr 17 '18 at 04:09
  • There is no default typing in the edited post. It's `Vec`, you can tell because you're calling `u64::from_string` which is a `Result`, and `expect` which unwraps that value. – Linear Apr 17 '18 at 04:28
  • I'm sure this is a duplicate of *something*, but I added an answer because I wasn't sure if this could truly be called a duplicate of the "default int literal type" problem linked in my answer. – MutantOctopus Apr 17 '18 at 04:51
  • Possible duplicate of [What is the {integer} in a compiler error message?](https://stackoverflow.com/questions/41996784/what-is-the-integer-in-a-compiler-error-message) – E_net4 Apr 17 '18 at 08:50
  • 1
    @E_net4 the original question was unrelated to integers (and without apparent duplicates), but I think the asker got discouraged by the comments; I don't know how to treat this question now, though. – ljedrz Apr 17 '18 at 09:08
  • @ljedrz Perhaps there could be a better duplicate target, all right. But let's put things this way: the question has already been answered, new answers are unlikely to add more value, and the duplicate completes the missing knowledge (the best answer there says that `i32` is the default integral type). There is nothing to be discouraged by, and the outcome turned out more positive than it could have been for a question which had its MCVE changed multiple times. – E_net4 Apr 17 '18 at 09:12

2 Answers2

15

Vec::new() relies on its context for information. When you push something to the vector, the compiler knows "oh, this is the kind of object I should be expecting". But since your example is pushing the integer literal 1, this appears to be related to the default type of an integer literal.

In Rust, an untyped integer literal will be assigned a value at compile time according to the context. For example:

let a = 1u8;
let b = 2;
let c = a + b;

b and c will be u8s; a + b assigns b to be the same type as a, and the output of the operation is a u8 as a result.

If no type is specified, the compiler appears to pick i32 (per this playground experiment). So in your specific example, and as seen in the playground, numbers would be a Vec<i32>.

MutantOctopus
  • 3,431
  • 4
  • 22
  • 31
  • This line makes the context very clear " When you push something to the vector, the compiler knows "oh, this is the kind of object I should be expecting". very precise answer. – Kajal Sinha Apr 18 '18 at 08:52
9

Vectors in Rust are generic, which means that they don't have a default type - unless by default you mean Vec<T> (T is a generic type parameter) or Vec<_> (_ is a type placeholder).

If the compiler doesn't find any related type annotation or isn't able to infer the element type using type inference, it will refuse to build the code:

let mut numbers = Vec::new();

error[E0282]: type annotations needed
 --> src/main.rs:2:23
  |
2 |     let mut numbers = Vec::new();
  |         -----------   ^^^^^^^^ cannot infer type for `T`
  |         |
  |         consider giving `numbers` a type

You can verify it further by trying to use a trick to find out the type of a variable:

let mut numbers = Vec::new();
let () = numbers;

error[E0308]: mismatched types
 --> src/main.rs:4:9
  |
3 |     let () = numbers;
  |         ^^ expected struct `std::vec::Vec`, found ()
  |
  = note: expected type `std::vec::Vec<_>` // Vec<_>
             found type `()`
ljedrz
  • 20,316
  • 4
  • 69
  • 97