Timmmm
Timmmm

Reputation: 96625

What trait can be used for scalar casts?

What trait can I restrict T to to allow this to compile?

fn one<T>() -> T {
    1.0 as _
}

fn main() {
    println!("{}", one::<i8>());
}

As-is, it gives this error:

rustc 1.14.0 (e8a012324 2016-12-16)
error: non-scalar cast: `f64` as `T`
 --> <anon>:2:5
  |
2 |     1.0 as _
  |     ^^^^^^^^

A good solution would be a trait that restricts T to primitive numeric types (i8, f64, etc.). I found std::num::Primitive but it's experimental apparently and the nightly compiler couldn't find it anyway.

Upvotes: 3

Views: 153

Answers (2)

Shepmaster
Shepmaster

Reputation: 430961

Answering the question you asked:

What trait can be used for scalar casts?

None. Traits only define methods and associated types. Scalar casts are built into the language and are not open for extension.

aochagavia has answered "how do I solve this problem".

Upvotes: 2

aochagavia
aochagavia

Reputation: 6246

There is a crate called num that provides some traits like the one you mention. You can find the documentation here. In your particular case, it seems that you should be able to use the One trait. This trait is, however, very limited because it only provides one function:

pub trait One: Mul<Self, Output=Self> {
    fn one() -> Self;
}

Depending on what you are trying to do, you are probably better off using the Num trait, which is a subtrait of Zero<Output=Self> + One<Output=Self> + Add<Self> + Sub<Self, Output=Self> + Mul<Self> + Div<Self, Output=Self> + Rem<Self, Output=Self> + PartialEq<Self>.

Both traits are implemented for the primitive numerical types (usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32, f64). Note, however, that they are also implemented for some types that are defined in the library (BigInt, BigUint, Ratio, Complex).

Upvotes: 2

Related Questions