Reputation: 85
I'm a beginner of Rust. I created an trait named Floating
, f32
and f64
implement this trait. A generic struct Vec
requiring that T
must implement Floating
trait. I would like to compute norm
of the vector, this won't compile with the error message said that no method named sqrt
found for type parameter T
in the current scope. Why this is happening and how would it work?
use std::ops::{Mul, Add};
trait Floating: Sized + Copy + Clone + Mul<Output=Self> + Add<Output=Self> {}
impl Floating for f32 {}
impl Floating for f64 {}
struct Vec<T: Floating> {
x: T,
y: T,
z: T,
}
impl<T: Floating> Vec<T> {
fn norm(&self) -> T {
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
}
}
fn main() {
let v: Vec<f32> = Vec {x: 1.0, y: 1.0, z: 1.0};
println!("norm is {:?}", v.norm());
}
Upvotes: 4
Views: 3025
Reputation: 26157
First of all, you probably shouldn't name your type Vec
, to avoid conflicts and confusion with the std::vec::Vec
container.
The issue is that (your) Vec
only knows that T
requires Floating
, and Floating
doesn't have a sqrt
method. So you need to define that yourself.
trait Floating: Sized + Copy + Clone + Mul<Output = Self> + Add<Output = Self> {
fn sqrt(self) -> Self;
}
impl Floating for f32 {
fn sqrt(self) -> Self {
f32::sqrt(self)
}
}
impl Floating for f64 {
fn sqrt(self) -> Self {
f64::sqrt(self)
}
}
This is where the num
crate comes in handy, as it defines a Float
trait, which includes among others a sqrt()
method. Using num
you can simplify your example to:
// num = "0.3"
use num::Float;
struct Vec<T: Float> {
x: T,
y: T,
z: T,
}
impl<T: Float> Vec<T> {
fn norm(&self) -> T {
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
}
}
fn main() {
let v: Vec<f32> = Vec {
x: 1.0,
y: 1.0,
z: 1.0,
};
println!("norm is {:?}", v.norm());
}
Upvotes: 5