go使用接口類型實現“模板類”

C++支持多態,可以通過重載和模板實現多態,其中模板類這個功能我感覺很方便,比如想寫一個棧類型,可以通過模板類,只定義一個類,就能讓這個棧支持int,double,char等多種數據類型。

go語言呢,不支持多態,自然也就沒有模板這個概念,但是沒有關係,go語言的設計者自然知道多態的好處,只是覺得重載這個概念不好理解,所以把多態這個東西給去掉了,取而代之的是一種更簡單的編程方式-接口

下面我們就來看看,如何使用接口實現C++的模板類。

使用接口實現模板類

首先,我們實現一個int類型的stack。

package mystack

import "errors"

type Mystack []int

func (stack *Mystack) Pop() (int, error) {
	if len(*stack) == 0 {
		return 0, errors.New("Pop error, stack is empty!")
	}
	tail := (*stack)[len(*stack)-1]
	*stack = (*stack)[:len(*stack)-1]
	return tail, nil
}

func (stack *Mystack) Push(val int) {
	*stack = append(*stack, val)
}

我們這裏定義了一個Mystack類型,其實就是一個int型切片,放在在mystack包裏,並且定義了兩個方法Push和Pop。接下來我們先看一下效果。

package main

import (
	"fmt"
	mystack "test/stack"
)

func main()  {
	stack := mystack.Mystack{1}
	fmt.Println(stack)
	stack.Push(2)
	fmt.Println(stack)
	stack.Pop()
	fmt.Println(stack)
}

運行結果如下:

歐克,現在我們想讓這個棧支持其他的類型,怎麼辦呢,很簡單,把切片類型由int改爲接口就可以了,剛纔的程序只要改3個地方:

既然改成了“模板類”,那測試函數自然也得搞複雜一些,多整幾種類型。

package main

import (
	"fmt"
	mystack "test/stack"
)

func main()  {
	stackInt := mystack.Mystack{1}
	stackByte := mystack.Mystack{'a'}
	stackString := mystack.Mystack{"abc"}
	fmt.Println("origin:", stackInt, stackByte, stackString)
	stackInt.Push(2)
	stackByte.Push('b')
	stackString.Push("efg")
	fmt.Println("after push:", stackInt, stackByte, stackString)
	stackInt.Pop()
	stackByte.Pop()
	stackString.Pop()
	fmt.Println("after push:", stackInt, stackByte, stackString)
}

運行結果如下:

這結果,對的不能再對了,也就是說,現在我們寫的這個Mystack,已經可以支持int,char,string等所有類型了。

通過把參數類型設置成interface{},我們就實現了將普通類轉化爲模板類,還是很簡單的吧,哈哈~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章