GORM不定參數(shù)的用法最佳實(shí)踐
引言
這篇文章介紹本人非常喜歡的一個(gè)經(jīng)驗(yàn):不定參數(shù)(即…運(yùn)算符)在GORM中的使用。
入門√——初級(jí)——中級(jí)——高級(jí);本文適應(yīng)入門及以上。
GORM最佳實(shí)踐之不定參數(shù)的用法
Go中的不定參數(shù)
在Golang的語(yǔ)言特性文檔中,對(duì)不定參數(shù)(… 參數(shù))進(jìn)行了專門的講解。當(dāng)在函數(shù)定義中聲明了一個(gè)不定參數(shù)…T
(比如 func Greeting(prefix string, who ...string)
)時(shí),在函數(shù)內(nèi)部就相當(dāng)于有了一個(gè)類型為[]T的變量(比如在Greeting
函數(shù)內(nèi),存在一個(gè)類型為[]string
的who
)。
如果有下面的Greeting函數(shù):
func Greeting(prefix string, who ...string){ fmt.Println(prefix, len(who), who) if len(who) > 0 { Greeting(prefix, who[1:]...) } }
那么可以通過(guò)Greeting("nobody")
和Greeting("hello:", "KiKi", "Joe", "Anna")
來(lái)調(diào)用Greeting
方法。對(duì)于前者用法來(lái)說(shuō),who
的值為nil
;對(duì)于后者用法來(lái)說(shuō),who
的值為[]string{"KiKi", "Joe", "Anna"}
。
這里需要注意兩點(diǎn):
1)不能直接傳入字符串切片調(diào)用Greeting("hello:", []string{"KiKi", "Joe", "Anna"})
,否則編譯器會(huì)報(bào)錯(cuò)。
2)也不能這么調(diào)用Greeting(prefix, who[1:])
,必須要傳入who[1:]...
。
這兩點(diǎn)基本上能揭露出不定參數(shù)的本質(zhì),它更像是聲明運(yùn)算過(guò)程而非數(shù)據(jù)類型
①當(dāng)在函數(shù)聲明中使用時(shí),做的是把函數(shù)調(diào)用時(shí)傳入的參數(shù)組裝成為切片(slice)
②當(dāng)在函數(shù)體內(nèi)部傳參使用時(shí),代表的是把切片中的數(shù)據(jù)拆組成為單個(gè)元素。恩,基本上就是這樣了。
GROM中不定參數(shù)的最佳實(shí)踐
說(shuō)實(shí)話,在剛開始接觸不定參數(shù)時(shí),并不覺(jué)得它存在的必要性;平日里編寫代碼很少用到它,感覺(jué)它就像是一個(gè)玩具,或者像是語(yǔ)言的一個(gè)噱頭。
直到最近在使用GROM的過(guò)程中,面對(duì)復(fù)雜的業(yè)務(wù)邏輯,當(dāng)model層定制的方法越來(lái)越多,總覺(jué)得力不從心。直到一次review代碼時(shí),經(jīng)過(guò)我們組賴?yán)蠋煹闹更c(diǎn),才算給我的代碼世界又打開了一扇新大門。
先看一段代碼:
// Topic 話題 type Topic struct { gorm.Model Title string `gorm:"index"` Content string `gorm:"type:text"` ViewCount int `json:"view_count"` ReplyCount int `json:"reply_count"` UserID int `gorm:"index" json:"user_id"` } // QueryByUserID 根據(jù)UserID獲取話題 func (t *Topic) QueryByUserID(userID int) (topics []Topic, err error) { db := config.DB.Where("user_id = ?", userID).Find(&topics).Error return }
為了根據(jù)用戶ID(UserID)獲取到相應(yīng)的話題(Topic),我們定義了一個(gè)QueryByUserID
的方法,為了表意這里刻意傳入了一個(gè)參數(shù);好像這個(gè)函數(shù)已經(jīng)能幫我們解決model層與controller的分離。但是如果真正使用時(shí)會(huì)發(fā)現(xiàn),其實(shí)這個(gè)函數(shù)有很大的局限性:它只能獲取某個(gè)UserID的所有的話題,卻無(wú)法實(shí)現(xiàn)對(duì)這個(gè)UserID下話題的進(jìn)一步篩選(比如獲取最近七天發(fā)布的話題)。
那么應(yīng)該如何定義這個(gè)Query函數(shù),使得我們使用時(shí)既優(yōu)雅又功能強(qiáng)大呢?答案便是不定參數(shù)。
試想,我們把QueryByUserID
函數(shù)以如下的方式定義:
// QueryByUserID 根據(jù)UserID獲取話題 func (t *Topic) QueryByUserID(userID int, args ...interface{}) (topics []Topic, err error) { db := config.DB.Where("user_id = ?", userID) if len(args) >= 2 { db = db.Where(args[0], args[1:]...) } else if len(args) >= 1 { db = db.Where(args[0]) } err = db.Find(&topics).Error return }
我們這里在QueryByUserID
的最后強(qiáng)行添加了一個(gè)args不定參數(shù),從而接受調(diào)用時(shí)傳入的附加的參數(shù)。同時(shí)在函數(shù)體內(nèi),我們根據(jù)args的長(zhǎng)度對(duì)它進(jìn)行不同方式的應(yīng)用,這就非常優(yōu)雅地?cái)U(kuò)展了QueryByUserID
的功能。根據(jù)GORM的特性,大量使用了Go的反射特性,查看源碼后知道這種用法完全可行。
在添加了不定參數(shù)的情況下,再調(diào)用QueryByUserID
的時(shí)候,想要進(jìn)一步精細(xì)地搜索話題,就方便多了。比如,想要獲取UserID為1且最近一周發(fā)布的話題,可以這么寫了:
topics, err := (&Topic{}).QueryByUserID(1, "created_at > ?", time.Now().Add(-7*24*time.Hour) // ... 其他對(duì)topics 與 err 的處理
非常靈活,好喜歡!
小結(jié)
本文對(duì)Go中的不定參數(shù)、GORM進(jìn)行了簡(jiǎn)單的介紹,并就二者的優(yōu)雅結(jié)合實(shí)踐進(jìn)行了描述。通過(guò)一個(gè)搜索某用戶發(fā)表的話題(Topic)的例子介紹了使用GORM時(shí)加入不定參數(shù)后所帶來(lái)的巨大靈活性。
通過(guò)這樣一種結(jié)合,能夠?qū)Σ欢▍?shù)以及GORM具有更深一步的認(rèn)識(shí),而認(rèn)識(shí)的夠深刻,開發(fā)起來(lái)就能更加得心應(yīng)手了??。
更多關(guān)于GORM不定參數(shù)用法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go語(yǔ)言基礎(chǔ)學(xué)習(xí)之Context的使用詳解
在Go語(yǔ)言中,Context是一個(gè)非常重要的概念,它用于在不同的?goroutine?之間傳遞請(qǐng)求域的相關(guān)數(shù)據(jù),本文將深入探討Go語(yǔ)言中?Context特性和Context的高級(jí)使用方法,希望對(duì)大家有所幫助2023-05-05golang?gorm框架數(shù)據(jù)庫(kù)的連接操作示例
這篇文章主要為大家介紹了golang?gorm框架數(shù)據(jù)庫(kù)操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04Golang實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能
這篇文章主要為大家詳細(xì)介紹了Golang實(shí)現(xiàn)斷點(diǎn)續(xù)傳、復(fù)制文件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07go string to int 字符串與整數(shù)型的互換方式
這篇文章主要介紹了go string to int 字符串與整數(shù)型的互換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07GoLang jwt無(wú)感刷新與SSO單點(diǎn)登錄限制解除方法詳解
這篇文章主要介紹了GoLang jwt無(wú)感刷新與SSO單點(diǎn)登錄限制解除方法,JWT是一個(gè)簽名的JSON對(duì)象,通常用作Oauth2的Bearer token,JWT包括三個(gè)用.分割的部分。本文將利用JWT進(jìn)行認(rèn)證和加密,感興趣的可以了解一下2023-03-03Go項(xiàng)目中添加生成時(shí)間與版本信息的方法
本文主要介紹了Go項(xiàng)目中添加生成時(shí)間與版本信息的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04