使两种结构与一种方法的实现不同

I want to make a min and max heap of integers:

package main

import (
    "container/heap"
    "fmt"
)

func main() {

    hi := make(IntHeap, 0)
    for number := 10; number >= 0; number-- {
        hi = append(hi, number)
    }
    heap.Init(&hi)
    fmt.Println(heap.Pop(&hi))
    fmt.Println(heap.Pop(&hi))
    fmt.Println(heap.Pop(&hi))
}

// An IntHeap is a min-heap of ints.
type IntHeap []int

func (h IntHeap) Len() int           { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

func (h *IntHeap) Push(x interface{}) {
    *h = append(*h, x.(int))
}

func (h *IntHeap) Pop() interface{} {
    old := *h
    n := len(old)
    x := old[n-1]
    *h = old[0 : n-1]
    return x
}

type IntMaxHeap IntHeap

func (h IntMaxHeap) Less(i, j int) bool { return h[i] > h[j] }

If I want to use IntMaxHeap instead, I am getting:

./median_stream.go:14: cannot use &hi (type *IntMaxHeap) as type heap.Interface in function argument:
        *IntMaxHeap does not implement heap.Interface (missing Len method)
./median_stream.go:15: cannot use &hi (type *IntMaxHeap) as type heap.Interface in function argument:
        *IntMaxHeap does not implement heap.Interface (missing Len method)
./median_stream.go:16: cannot use &hi (type *IntMaxHeap) as type heap.Interface in function argument:
        *IntMaxHeap does not implement heap.Interface (missing Len method)
./median_stream.go:17: cannot use &hi (type *IntMaxHeap) as type heap.Interface in function argument:
        *IntMaxHeap does not implement heap.Interface (missing Len method)

How can I make two structs ("classes") which differ with just one method implementation? The working version should print 3 biggest numbers from the heap.

When you declare a new type in Go, it doesn't inherit the methods of the underlying type. If you do want to inherit methods, consider using composition:

type IntMaxHeap struct {
    IntHeap
}

func (h IntMaxHeap) Less(i, j int) bool { return h.IntHeap[i] > h.IntHeap[j] }

If you have a primed IntHeap (or any []int slice, for that matter), you can construct this type with IntMaxHeap{slice} without needing to reimplement the other methods.

This pattern can be quite useful to declare multiple orderings for use with the sort package, without duplicating methods.

Short answer: you can't. Go has no method inheritance. The shortest you could get is by using anonymous fields (see the spec about struct types), but you will lose the slice mechanics.

You will have to re-implement the interface for each type. But you can do it smartly, by using an unexported function to do the job, and just return the result of this function. That could save you a few typing and ensure your methods have the same inner workings.

Example:

type A []int

func (a A) Len() int {
    return getLen(a)
}

type B []int

func (b B) Len() int {
    return getLen(a)
}

func getLen(slice []int) int {
    return len(slice)
}

Obviously my example is dumb, because I'm just wrapping the len built-in, but for longer functions (say, other that oneliners), it is quite useful.