2014-06-20 73 views
0

我要讓整數的最小和最大堆:使兩個結構與一個方法不同實現

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] } 

如果我想使用IntMaxHeap相反,我得到:

./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) 

我怎樣才能製作兩個結構(「類」),這些結構與僅僅一個方法實現有所不同?工作版本應該從堆中打印3個最大的數字。

回答

2

當您在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包一起使用的多個訂單,而無需重複方法。

1

簡答:你不行。 Go沒有方法繼承。您可以使用的最短的匿名字段(請參閱spec about struct types),但您將失去切片機制。您將不得不重新實現每種類型的接口。但你可以巧妙地做到這一點,通過使用未導出的函數來完成這項工作,並返回這個函數的結果。這可以爲您節省一些打字工作,並確保您的方法具有相同的內部工作方式。

例子:

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),它是非常有用的。

相關問題