Earlier quoted context omitted.
> Except where they can't, and those locations aren't terribly consistent. Why aren't they consistent? The Rust type inference is generally very good, and the places where you have to annotate are places where any typechecker would force you to annotate, because the types are simply underconstrained (e.g. the return type of Vec::collect or mem::transmute). > The Rust designers have publicly announced their preference…
> Why aren't they consistent? So, I went back to do a bit of research, and it's gotten better since this first bothered me, my apologies. My beef was with the `let x = vet::Vector::New:: ()` vs `let x: Vec = vec::Vec::New()`. Perhaps not the best way to word it, so consider this objection retracted. :) > the idea that we intentionally made the type inference less powerful than it could have been is totally false Exce…
To summarize: bare FP literals default to f64, bare integral literals default to isize. (NOTE: isize is recently renamed from int. It is a pointer-sized integer.)
(EDIT: The default for integer literals may be superseded by a later RFC. I seem to recall that the default is actually i32 now, but I can't find a PR to back up that claim.)
So you could easily get a Vec3 like so:
let mut s = Vec3 { x: 0.0, y: 0.0, z: 0.0, w: 0.0 };
let mut t = Vec3 { x: 0f64, y: 0.0, z: 0.0, w: 0.0 };
The key here is that integral literals and floating point literals are distinct.A bare literal of the form `0` is an unconstrained integral literal.
Whereas a literal of the form `0.0` or `.0` is an unconstrained float literal.
In practice it is very rare for me to annotate my numeric literals. If the variable escapes the stack frame it will be constrained by the signature of the function anyways. If not I constrain the type inline (`let x: T = ...`) and use the appropriate bare literals.