#go
#Вперед
Вопрос:
Я хочу создать минимальную и максимальную кучу целых чисел:
package main
import (
"container/heap"
"fmt"
)
func main() {
hi := make(IntHeap, 0)
for number := 10; number >= 0; number-- {
hi = append(hi, number)
}
heap.Init(amp;hi)
fmt.Println(heap.Pop(amp;hi))
fmt.Println(heap.Pop(amp;hi))
fmt.Println(heap.Pop(amp;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] }
Если я хочу использовать IntMaxHeap
вместо этого, я получаю:
./median_stream.go:14: cannot use amp;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 amp;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 amp;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 amp;hi (type *IntMaxHeap) as type heap.Interface in function argument:
*IntMaxHeap does not implement heap.Interface (missing Len method)
Как я могу создать две структуры («классы»), которые отличаются только одной реализацией метода? Рабочая версия должна печатать 3 самых больших числа из кучи.
Ответ №1:
Когда вы объявляете новый тип в Go, он не наследует методы базового типа. Если вы хотите наследовать методы, рассмотрите возможность использования композиции:
type IntMaxHeap struct {
IntHeap
}
func (h IntMaxHeap) Less(i, j int) bool { return h.IntHeap[i] > h.IntHeap[j] }
Если у вас есть загрунтованный IntHeap
(или любой []int
фрагмент, если на то пошло), вы можете создать этот тип IntMaxHeap{slice}
без необходимости переопределения других методов.
Этот шаблон может быть весьма полезен для объявления нескольких порядков для использования с sort
пакетом без дублирования методов.
Ответ №2:
Короткий ответ: вы не можете. Go не имеет наследования метода. Самое короткое, что вы могли бы получить, — это использовать анонимные поля (см. Спецификацию о типах структур), но вы потеряете механику среза.
Вам придется повторно реализовать интерфейс для каждого типа. Но вы можете сделать это разумно, используя неэкспортируемую функцию для выполнения задания и просто возвращая результат этой функции. Это может сэкономить вам немного времени на вводе текста и обеспечить, чтобы ваши методы имели одинаковую внутреннюю работу.
Пример:
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)
}
Очевидно, что мой пример глуп, потому что я просто оборачиваю len
встроенное, но для более длинных функций (скажем, кроме oneliners) это весьма полезно.