Extend Packages

All struct methods must be placed in the same package. They can be stored in different files.

If we want to extend packages provided by the other developers, what to do? In other OOP languages, we could inherit the original classes, but there’s no inheritance in Go.

How to extend system types or 3rd party types?

In Go, there are two solutions:

  • Use compositions
  • Define alternative names

Use Composition

In our TreeNode data structure, the Traverse method uses in-order traversal.

If we want to implement a post-order traversal, we can refactor the following:

In entry.go file,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
"fmt"
"learngo/tree"
)

type myTreeNode struct {
node *tree.Node
}

func (myNode *myTreeNode) postOrder() {
if myNode == nil || myNode.node == nil {
return
}

left := myTreeNode{myNode.node.Left}
right := myTreeNode{myNode.node.Right}
left.postOrder()
right.postOrder()
myNode.node.Print()
}

func main() {
var root tree.Node
root = tree.Node{Value: 3}
root.Left = &tree.Node{}
root.Right = &tree.Node{5, nil, nil}
root.Right.Left = new(tree.Node)
root.Left.Right = tree.CreateNode(2)

root.Traverse()
fmt.Println()
myRoot := myTreeNode{&root}
myRoot.postOrder()
fmt.Println()
}

Now we print both in-order and post-order traversal results:

1
2
3
4
5
6
7
8
9
10
11
12
In Order
0
2
3
0
5
Post Order
2
0
0
5
3

Use Alternative Name

Let’s use alternative name method to implement a queue. We could borrow some slice features to implement a queue.

Create a package queue and add a queue.go file in the package.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package queue

type Queue []int

func (q *Queue) Push(v int) {
*q = append(*q, v)
}

func (q *Queue) Pop() int {
head := (*q)[0]
*q = (*q)[1:]
return head
}

func (q *Queue) IsEmpty() bool {
return len(*q) == 0
}

In the package, create a sub-folder entry and create a file entry.go for entry point.

In entry.go:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
"learngo/queue"
)

func main() {
q := queue.Queue{1}
q.Push(2)
q.Push(3)
q.Push(4)
q.Push(5)
fmt.Println(q.Pop())
fmt.Println(q.Pop())
fmt.Println(q.IsEmpty())
q.Pop()
q.Pop()
q.Pop()
fmt.Println(q.IsEmpty())
}

The output will be:

1
2
3
4
1
2
false
true