Try to understant generics

Hi, I try to rewrite this Rosetta Code example

I want to make it more generic and (hopefully) more idiomatic. But I struggle with a generic function


#[derive(Debug, Clone)]
struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn new(x1: T, y1: T) -> Point<T> {
        Point { x: x1, y: y1 }
    }
}

fn lowest_point(points: &Vec<Point<T>>) -> Result {
    points
        .iter()
        .enumerate()
        .min_by(|lhs, rhs| lhs.1.y.partial_cmp(&rhs.1.y).unwrap())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_one() {
        let points = vec![
            Point::new(16., 3.),
            Point::new(12., 17.),
            Point::new(0., 6.),
            Point::new(-4., -6.),
            Point::new(16., 6.),
            Point::new(16., -7.),
            Point::new(16., -3.),
            Point::new(17., -4.),
            Point::new(5., 19.),
            Point::new(19., -8.),
            Point::new(3., 16.),
            Point::new(12., 13.),
            Point::new(3., -4.),
            Point::new(17., 5.),
            Point::new(-3., 15.),
            Point::new(-3., -9.),
            Point::new(0., 11.),
            Point::new(-9., -3.),
            Point::new(-4., -2.),
            Point::new(12., 10.),
        ];
        println!("{:?}", points);
        // let lowest = lowest_point(points);
        // println!("{:?}", lowest);
        // assert!(lowest)
    }
}

I have problems with the function "lowest_point". I don't know how the function signature should look like.

Well, you want the type to be something you can call partial_cmp on. That is the PartialOrd trait, so you can require it like this:

fn lowest_point<T>(points: &Vec<Point<T>>)
where
    T: PartialOrd,
{

Or via the short-hand notation:

fn lowest_point<T: PartialOrd>(points: &Vec<Point<T>>) {
2 Likes

This was quick and helpful, a big thank you. Here is my solution so far


#[derive(Debug, Clone)]
struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn new(x1: T, y1: T) -> Point<T> {
        Point { x: x1, y: y1 }
    }
}

fn lowest_point<T: PartialOrd>(points: &Vec<Point<T>>) -> Option<(usize, &Point<T>)> {
    points
        .iter()
        .enumerate()
        .min_by(|lhs, rhs| lhs.1.y.partial_cmp(&rhs.1.y).unwrap())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_one() {
        let points = vec![
            Point::new(16., 3.),
            Point::new(12., 17.),
            Point::new(0., 6.),
            Point::new(-4., -6.),
            Point::new(16., 6.),
            Point::new(16., -7.),
            Point::new(16., -3.),
            Point::new(17., -4.),
            Point::new(5., 19.),
            Point::new(19., -8.),
            Point::new(3., 16.),
            Point::new(12., 13.),
            Point::new(3., -4.),
            Point::new(17., 5.),
            Point::new(-3., 15.),
            Point::new(-3., -9.),
            Point::new(0., 11.),
            Point::new(-9., -3.),
            Point::new(-4., -2.),
            Point::new(12., 10.),
        ];
        let lowest = lowest_point(&points).unwrap();
        assert!(lowest.0 == 15);
        assert!(lowest.1.x == -3.0);
        assert!(lowest.1.y == -9.0);
    }
}

I suspect I will have many more problems with such functions until I understand it.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.