-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: accepting generic dimension for calculation in specific units #64
Comments
The easiest way to do this is to accept something that can convert into Kelvin. You will also need to call Example: use dimensioned::{si, Dimensionless};
impl TemperatureDependence for MyStruct {
fn apply<T>(&self, n: Vector3<f64>, temperature: T) -> Vector<f64>
where T: Into<si::Kelvin<f64>> {
// --snip--
let f: f64 = *((temperature.into() - 20.0 * si::K) / si::K).value();
// --snip--
// returns a vector based on this
}
} If you really want to accept anything that is a |
That's fantastic! Thanks. Everything makes sense to me except for dereferencing that computation. Presumably those brackets return a reference... but i'm not sure why. And doesn't calling a method on a reference automatically dereference it? |
|
Ohhh I see. I got the order of operations mixed up. But now that I think about it, if I implement the function with this trait requirement and try to write another function that uses this one, won't that requirement ascend up the chain? Do I have to constantly worry about eg: fn otherFn<Q, T>( &tempDep: Q, n: Vector3<f64>, temp: T) -> Vector3<f64>
where
Q: TemperatureDependence,
T: Into<si::Kelvin<f64>> // do I need to worry about this every time I use a temperature now?
{
tempPep.apply(n, temp)
} |
For what it's worth, I would be happy to see see this change, and update my own code to deal with it. Overall, it would simplify things. |
Yeah, that's how generics in Rust work. Alternatively, those functions "up the chain" could accept any concrete type that implements that trait, such as taking
I have a few breaking changes in mind that I'd like to save until I can replace typenum with const generics. This is one of them. |
Oh that's too bad. I was hoping this library would implement something more along the lines of this: This strategy allows for accepting a Length in any units without declaring the input units. fn circumference<T>(r: Length<T>) -> Length<T> where T: LengthUnit {
2 * r * std::f64::consts::PI
}
fn main() {
let l1 = millimeters!(10);
let l2 = meters!(5);
let l3 = (5 * l1) + l2;
let l3_meters = f64::from(meters!(l3));
let c1 = circumference(l1);
println!("l1 = {}", l1);
println!("l2 = {}", l2);
println!("l3 = (5 * l1) + l2 = {}", l3);
println!("l3_meters = {}", l3_meters);
println!("circumference(radius = {}) = {}", l1, c1);
println!("l3 > l2 : {}", l3 > l2);
println!("l3 / l2 = {}", l3 / l2);
} |
It allows the appearance of accepting a Length in any units. In reality, lengths are only represented as nanometers. If you need to operate with greater than nanometer precision, or at astronomical distances, that type is useless. Dimenionsed takes an alternate approach, letting you represent values in any units you wish, with the precision you wish, with the trade-off of additional boilerplate for generic functions. You could achieve something similar in Dimensioned by, for example, just using |
Ok i guess I'm trying to write my code to generally and I should just be using Kelvin |
Here's what that example might look like in dimensioned: use dimensioned::{si, f64prefixes::*};
fn circumference(r: si::Meter<f64>) -> si::Meter<f64> {
2.0 * r * std::f64::consts::PI
}
fn main() {
let l1 = 10.0 * MILLI * si::M;
let l2 = 5.0 * si::M;
let l3 = (5.0 * l1) + l2;
let l3_meters = l3.value_unsafe;
let c1 = circumference(l1);
println!("l1 = {}", l1);
println!("l2 = {}", l2);
println!("l3 = (5 * l1) + l2 = {}", l3);
println!("l3_meters = {}", l3_meters);
println!("circumference(radius = {}) = {}", l1, c1);
println!("l3 > l2 : {}", l3 > l2);
println!("l3 / l2 = {}", l3 / l2);
} The difference here is that all prints will be in meters, it would be up to you to output in a different unit if desired. |
ok thanks! |
(I'm sorry. I'm very new to rust and having a hard time understanding the type system.)
What I'm trying to achieve is a method on a struct that accepts any temperature, and uses it in a calculation to return a unitless value.
I'm trying to do something like this:
But I get the error:
I feel like i'm missing something, because i don't actually want to make this THAT generic. I feel like any type that implements
trait Temperature
should be able to be converted into Kelvin... so what gives? How do i do this?Thanks in advance.
The text was updated successfully, but these errors were encountered: