I was following along with this tutorial on creating a concurrent counter struct for a usize value: ConcurrentCounter. As I understand it, this wrapper struct allows us to mutate our usize value, with more concise syntax, for example:my_counter.increment(1) vs. my_counter.lock().unwrap().increment(1).
Now in this tutorial our value is of type usize, but what if we wanted to use a f32, i32, or u32 value instead?
I thought that I could do this with generic type arguments:
use std::{sync::{Arc, Mutex}};
#[derive(Clone)]
pub struct ConcurrentCounter<T>(Arc<Mutex<T>>);
impl<T> ConcurrentCounter<T>{
pub fn new(val:T) -> Self {
ConcurrentCounter(Arc::new(Mutex::new(val)))
}
pub fn increment(&self, by: T) {
let mut counter = self.0.lock().unwrap();
*counter = *counter + by;
}
pub fn decrement(&self, by: T) {
let mut counter = self.0.lock().unwrap();
*counter = *counter - by;
}
pub fn multiply(&self, by: T) {
let mut counter = self.0.lock().unwrap();
*counter = *counter * by;
}
pub fn get(&self) -> T {
let counter = self.0.lock().unwrap();
*counter
}
}
But this yields error:
cannot add `T` to `T`
cannot subtract `T` from `T`
cannot multiply `T` by `T`
I know I need to provide some trait restrictions for my type arguments, but I'm unsure what exactly those arguments are. I know that you can't do everything you can do with an i32 with a f32, but I just need to use the counter for some simple operations and it seems silly use a different wrapper struct for primitive number types. So how would I get my ConcurrentCounter struct working, or is there maybe a library that provides such a counter?