How to pass a Fn parameterized by type T?

#1

I have this code which works fine:

struct Matcher<'a, T>
where
    T: 'a + Sized + Hash + Eq,
{
    a: &'a [T],
    b: &'a [T],
}

impl<'a, T> Matcher<'a, T>
where
    T: 'a + Sized + Hash + Eq,
{
    pub fn new(a: &'a [T], b: &'a [T]) -> Matcher<'a, T> {
        Matcher { a, b }
    }
}

When complete, this depends on T implementing ==.
However, I want to be able to pass an arbitrary is_equal function because it may be different from ==.
I’ve tried this but it won’t build:

type IsEqualFn<T> = Fn(&T, &T) -> bool;

struct Matcher<'a, T>
where
    T: 'a + Sized + Hash + Eq,
{
    a: &'a [T],
    b: &'a [T],
    is_equal: IsEqualFn<&'a T>,
}

impl<'a, T> Matcher<'a, T>
where
    T: 'a + Sized + Hash + Eq,
{
    pub fn new(a: &'a [T], b: &'a [T], is_equal: IsEqualFn<&'a T>) -> Matcher<'a, T> {
        Matcher { a, b, is_equal }
    }
}

This gives me an error of “doesn’t have a size known at compile-time”, but the link is to the second edition of the book which doesn’t seem to be available.

Is what I’m trying possible?

0 Likes

#2

You need to do it slightly differently, using a generic trait bound: example

1 Like

#3

Thank you, that worked superbly!

1 Like

#4

It might also be helpful to look at how the stdlib handles the problem of doing something with a user-supplied matching predicate such as Iterator::position.

1 Like

#5

@mark, I saw you were asking about a convenience function for a specific type. Yes, you can do that if you want: example.

0 Likes

#6

Thank you:-) I really should have seen that for myself.

0 Likes