[golang]讓golang支援泛型程式設計的一個方案實現

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。本部落格原創博文著作權 @Allyvipally@gmail.com僅供交流學習使用用於商業用途請聯絡原作者 轉載請註明出處:http://blog.sina.com.cn/ally2014
總所周知,golang現在不支援泛型程式設計,對於習慣了C++泛型程式設計思想的程式員來說無疑是一個硬傷。雖然golang interface{}多少可以滿足一些泛型需求,但是無論在效率和編程手法上,都無法達到C++template那樣的靈活性。出於對編譯器效率的考慮,官方暫時還沒有golang支援泛型的方案。根據C++泛型的基本思路,我實現了一個名為gpg[1]的工具,使用工具通過文字替換的方式產生需要的.go代碼,解決維護多個相似代碼的尷尬,通過配置.gpg(ini)執行個體化模板檔案(.gp),替換相關模板參數達到維護一份代碼(.gp),實作類別型無關的編程思想。
如源碼中example所示,假如需要實現一個未知類型的全域變數,需要在get和set的時候自動加鎖,解決不同goroutine訪問全域變數時的衝突。按照現有go規則,使用interface{}每次進行類型斷言是一個辦法,但是應用起來代碼不好看,執行效率也沒有原生類型快。還有一個辦法是用到什麼類型,就把已經實現的代碼拷貝一份改一改類型,這樣一旦演算法有修改,需要修改所有的實現代碼,很不靠譜。gpg可以解決以上所有問題. gpg的使用方法如下:gpg tool 使用方法:gpg-h    顯示協助gpg       遍曆目前的目錄所有.gpg檔案 用同名的.gp檔案作為模板產生.go代碼檔案gpg 遍曆path目錄所有.gpg檔案 用同名的.gp檔案作為模板產生.go代碼檔案//////////////////////////////////////////example.gp//This is an example of using gpg tool forgeneric-programming
//this is an example of using gpg to define an auto-lock globalvalue with generic type
//it will be realized to real go code by gpg tool through the .gpgfile with the same name
package exampleimport (
 "sync"
)//auto locked global value
type AutoLockGbl struct {
 val 
 lock sync.RWMutex
}//new and init a global value
func New(val ) *AutoLockGbl{
 p := &AutoLockGbl{}
 p.val = val
 return p
}//get value, if modify is disable, lock is unneeded
func (me *AutoLockGbl) Get() (r ) {
 me.lock.RLock()
 defer me.lock.RUnlock()
 r = me.val
 return
}//set value, if modify is disable, delete this function
func (me *AutoLockGbl) Set(val ) (r ) {
 me.lock.Lock()
 defer me.lock.Unlock()
 r = me.val
 me.val = val
 return
}
//////////////////////////////////////////example.gpg//分別用int,string,uint64執行個體化example.gp;this is exactlly an ini file
;it is used to generate code from .gp file
[int]
TYPE_NAME=Int
VALUE_TYPE=int
LOCK_COMMENT= ;禁止修改,不需要鎖[const_str]
TYPE_NAME=ConstStr
VALUE_TYPE=string
LOCK_COMMENT=// ;禁止修改,不需要鎖[const_u64]
TYPE_NAME=ConstU64
VALUE_TYPE=uint64
LOCK_COMMENT=//
可以得到形如以下的代碼檔案/////////////////////////////////example_gpg_int.go// This file was auto-generated by [gpg] tool
// Last modify at: 2014-01-21 13:06:46.6378366 +0800 +0800
// !!!!!!!!!NEVER MODIFY IT MANUALLY!!!!!!!!!//Copyright @Ally 2014. All rights reserved.
//Version:   1.0.0
//Author:   vipally@gmail.com
//Blog site: http://blog.sina.com.cn/ally2014//This is an example of using gpg tool forgeneric-programming
//this is an example of using gpg to define an auto-lock globalvalue with generic type
//it will be realized to real go code by gpg tool through the .gpgfile with the same name
package exampleimport (
 "sync"
)//auto locked global value
type AutoLockGblInt struct {
 val  int
 lock sync.RWMutex
}//new and init a global value
func NewInt(val int) *AutoLockGblInt{
 p := &AutoLockGblInt{}
 p.val = val
 return p
}//get value, if modify is disable, lock is unneeded
func (me *AutoLockGblInt) Get() (r int) {
 me.lock.RLock()
 defer me.lock.RUnlock()
 r = me.val
 return
}//set value, if modify is disable, delete this function
func (me *AutoLockGblInt) Set(val int) (r int) {
 me.lock.Lock()
 defer me.lock.Unlock()
 r = me.val
 me.val = val
 return
} /////////////////////////////////example_gpg_const_str.go// This file was auto-generated by [gpg] tool
// Last modify at: 2014-01-21 13:06:46.6408372 +0800 +0800
// !!!!!!!!!NEVER MODIFY IT MANUALLY!!!!!!!!!//Copyright @Ally 2014. All rights reserved.
//Version:   1.0.0
//Author:   vipally@gmail.com
//Blog site: http://blog.sina.com.cn/ally2014//This is an example of using gpg tool forgeneric-programming
//this is an example of using gpg to define an auto-lock globalvalue with generic type
//it will be realized to real go code by gpg tool through the .gpgfile with the same name
package exampleimport (
 //"sync"
)//auto locked global value
type AutoLockGblConstStr struct {
 val  string
 //lock sync.RWMutex
}//new and init a global value
func NewConstStr(val string) *AutoLockGblConstStr{
 p := &AutoLockGblConstStr{}
 p.val = val
 return p
}//get value, if modify is disable, lock is unneeded
func (me *AutoLockGblConstStr) Get() (r string) {
// me.lock.RLock()
// defer me.lock.RUnlock()
 r = me.val
 return
}//set value, if modify is disable, delete this function
//func (me *AutoLockGblConstStr) Set(val string) (r string) {
// me.lock.Lock()
// defer me.lock.Unlock()
// r = me.val
// me.val = val
// return
//}


這樣基本可以滿足golang對泛型的需求,而不需要付出額外代價。
本部落格原創博文著作權 @Allyvipally@gmail.com僅供交流學習使用用於商業用途請聯絡原作者 轉載請註明出處:http://blog.sina.com.cn/ally2014
[1] gpg源碼   https://github.com/vipally/gpg

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.