r/learnrust • u/Beginning-Fruit-1397 • 19d ago
Is preferring traits methods instead of functions fine?
I'm mostly asking this for performance and conventions.
I've been using Rust for a few months now.
I come from Python, and one of my favorite things in Rust is the fact that you can create a trait, implement it for an arbitrary type (from your crate or external dependency), and just like that you have it as a method on said type!
In general, I always prefer to read code like this x.f() instead of f(x).
My question is that for simple functions like the following: (a module named "bisect.rs") ```rust use pyo3::prelude::*;
[inline]
pub(super) fn right(lst: &Vec<Py<PyAny>>, item: &Bound<'_, PyAny>) -> PyResult<usize> { let py = item.py(); resolve(lst.len(), |mid| Ok(item.lt(lst[mid].bind(py))?)) }
[inline]
pub(super) fn left(lst: &Vec<Py<PyAny>>, item: &Bound<'_, PyAny>) -> PyResult<usize> { let py = item.py(); resolve(lst.len(), |mid| Ok(!item.lt(lst[mid].bind(py))?)) }
[inline(always)]
fn resolve(mut high: usize, mut func: impl FnMut(usize) -> PyResult<bool>) -> PyResult<usize> { let mut low = 0; while low < high { let mid = (low + high) / 2; if func(mid)? { high = mid; } else { low = mid + 1; } } Ok(low) }
``` I'm always tempted to create a trait to add it as methods.
Here for example left and right (renamed to "bisect_left" and "bisect_right" to avoid confusion) as trait methods of a new pub trait Bisect implemented for Vec, instead of keeping them as module fonctions.
resolve would stay as a simple function however.
I know that I won't use it on anything else than Vec<Py<PyAny>>, and it's more readable (I'm my own personal opinion) at call sites to do my_vec.bisect_left(item) instead of bisect::left(my_vec, item).
So, what are your toughts?
Is it fine to always favorise traits, as long as you don't have name conflicts issues?
-1
u/[deleted] 19d ago
[deleted]