3

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.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Timmmm
  • 88,195
  • 71
  • 364
  • 509
  • Duplicate of http://stackoverflow.com/q/29025811/155423; http://stackoverflow.com/q/30942408/155423; http://stackoverflow.com/q/29184358/155423; http://stackoverflow.com/q/30057726/155423; http://stackoverflow.com/q/30044026/155423; http://stackoverflow.com/q/21073709/155423; http://stackoverflow.com/q/37296351/155423; etc. – Shepmaster Dec 24 '16 at 16:52
  • Thanks for the links. Lots of similar questions (maybe an opportunity to improve the book!). The most helpful answer I think it [this one](http://stackoverflow.com/a/29032520/265521). – Timmmm Dec 24 '16 at 17:59

2 Answers2

2

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).

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
aochagavia
  • 5,887
  • 5
  • 34
  • 53
2

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".

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Aren't some traits like `Sync` and `Copy` 'magic'? If so I don't think it is unreasonable to expect a magic `Primitive` trait. – Timmmm Dec 25 '16 at 12:13