GoLang实现自定义类型的匿名函数

I have completed the strains exercise on exercism.io. I am refactoring my solution. For context: Ints.Keep takes in a predicate function and returns a filtered slice of type Ints for every element where the predicate function is true. Conversely Discard returns all elements for which the predicate is not true. Discard returns the inverse of Keep. I implemented it like so:

func (i Ints) Keep(pred func(int) bool) (out Ints) {
    for _, elt := range i {
        if pred(elt) {
            out = append(out, elt)
        }
    }
    return
}

func (i Ints) Discard(f func(int) bool) Ints {
    return i.Keep(func(n int) bool { return !f(n) })
}

Example usage

Now I am trying to clean it up slightly. I want to create:

type Predicate func(int) bool

Then I want to implement Keep and Discard where the input is a Predicate. I run into the issue when I try to create an anonymous function within Discard to return Keep:

func (i Ints) Discard(p Predicate) Ints {
    return i.Keep(Predicate(n int) { return !p(n) })
}

Is this possible? I can't find a way to create an anonymous function of a named func type.

You can do it by casting the anonymous function as a Predicate Like this:

func (i Ints) Discard(p Predicate) Ints {
    return i.Keep(Predicate(func(i int) bool { return !p(i) }))
}

This isn't quite as clean as I wanted, but I bet this is the best.

I guess you are misunderstanding text replacement with type subtitution, see:

  • f func(int) bool gets replaced by p Predicate
  • func and bool (wrapping (n int)) somehow gets replaced by Predicate.

As far i remember type substitution is very straightforward and that is not the case here... "Mu is too short" highlights a good example if you insist on using type... although it is perfect to use anonymous functions definitions and declarations.

Another way to write code that comes to my mind that you might find useful is:

type Predicate func(int) bool

func (i Ints) Discard(pred Predicate) Ints {
    var anonymousComplementFunc Predicate = func(n int) bool {
        return !pred(n)
    }
    return i.Keep(anonymousComplementFunc)
}