I have a trait that genericizes getting a (audio, etc) sample from a "signal":
pub trait Signal {
/// When requested, all signals must produce a f64 sample.
fn evaluate(&mut self) -> f64;
}
I wanted to implement this trait for plain-old f64
s and make it just keep on returning the same value instead of making a whole different struct that implements Signal
to do the same thing:
impl Signal for f64 {
fn evaluate(&mut self) -> f64 {
*self
}
}
It turns out that this doesn't matter anyway; even if I make said struct, when I try to give a default value it doesn't work either way.
In one of my signal generators, I'd like to switch over from using a f64
type:
// Sine implements Signal
pub struct Sine {
frequency: f64,
// Other fields omitted
}
To a Signal
type, to be able to have the frequency change over time:
pub struct Sine<F> where
F: Signal,
{
frequency: F,
// Other fields omitted
}
The problem arises when I go to make a Sine::new()
function that tries to default the parameterized type (NOTE that I needed to use parameterized types to capture a trait type instead of using references due to a previous issue with borrowing I had with rust-portaudio
):
impl<F> Sine<F> where
F: Signal,
{
/// Creates a new Sine wave signal generator.
pub fn new() -> Sine<F> {
Sine {
frequency: 444.0,
// Other fields omitted
}
}
}
I get the following error:
error[E0308]: mismatched types
--> src/dsp/generators/sine.rs:35:24
|
35 | frequency: 444.0,
| ^^^^^ expected type parameter, found floating-point variable
|
= note: expected type `F`
found type `{float}`
This same struct definition works fine as long as I have a new()
where you explicitly pass in a type that implements Signal
:
let sine_gen1 = generators::Sine::new(440.0);
but I would like to be able to default values instead of passing all of the arguments all of the time.
A few other things I've tried:
444.0 as F
error[E0605]: non-primitive cast: 'f64' as 'F' (error[E0605]: non-primitive cast: 'f64' as 'F')
440.0_f64 as Signal
error[E0620]: cast to unsized type: 'f64' as 'dsp::traits::Signal'
- Making a new struct (called
Constant
) that takes in af64
in its ownnew()
function and implementsSignal
, then making an instance of that struct inSine::new()
and trying to set it tofrequency
- I haven't found a combination of doing this that seems to work, plus it kind of feels too hacky to be correct.