Go語言常見錯誤之濫用getters/setters誤區(qū)實例探究
理解Go中的封裝
在開始之前,有必要了解Go語言中的封裝原則。在許多面向?qū)ο蟮恼Z言中,封裝通常通過使用私有字段(private)和公共方法(public)(即getters和setters)來實現(xiàn)。然而,在Go中,并沒有明確的“private”和“public”關(guān)鍵字,而是通過大寫字母開頭的標(biāo)識符來表達(dá)公有(可導(dǎo)出的)成員,小寫字母開頭的標(biāo)識符表示私有(非導(dǎo)出的)成員。
常見誤區(qū)
誤區(qū)一:為每個字段創(chuàng)建getter和setter
一個常見的錯誤是為結(jié)構(gòu)體中的每個字段都創(chuàng)建getter和setter方法,即使它們不需要特殊邏輯來訪問或修改。
例子:
type Person struct { name string } func (p *Person) GetName() string { return p.name } func (p *Person) SetName(name string) { p.name = name }
如何避免:
在Go中,如果字段不需要特殊的訪問控制,那么它們應(yīng)該被直接暴露,而不是通過getter和setter。
改進(jìn)后的例子:
type Person struct { Name string }
誤區(qū)二:getter和setter中的不必要邏輯
避免在getter和setter中增加不必要的邏輯,因為這些額外的步驟可能不是調(diào)用者預(yù)期的。
例子:
func (p *Person) GetName() string { return "Name: " + p.name // Unnecessary formatting } func (p *Person) SetName(name string) { p.name = strings.TrimSpace(name) // Unnecessary trimming }
如何避免:
Getter應(yīng)只返回值,setter應(yīng)只設(shè)置值。如果需要對數(shù)據(jù)進(jìn)行格式化或清理,請使用單獨的方法來明確這些意圖。
改進(jìn)后的例子:
type Person struct { Name string } func (p *Person) SetName(name string) { p.Name = name } func (p *Person) FormattedName() string { return "Name: " + p.Name } func (p *Person) CleanName() { p.Name = strings.TrimSpace(p.Name) }
誤區(qū)三:setter方法返回值
在Go中,setter方法一般不應(yīng)該有返回值,因為這可能會導(dǎo)致混亂。
例子:
func (p *Person) SetName(name string) bool { if name == "" { return false } p.name = name return true }
如何避免:
將setter方法設(shè)計為void函數(shù)。如果需要錯誤處理,可以考慮返回error類型。
改進(jìn)后的例子:
func (p *Person) SetName(name string) error { if name == "" { return errors.New("name cannot be empty") } p.Name = name return nil }
誤區(qū)四:違反Go語言的約定
在一些其他語言中,使用get和set前綴是普遍的命名約定。而在Go中,通常省略這些前綴,應(yīng)遵循Go的簡潔和直率的命名風(fēng)格。
例子:
func (p *Person) GetAge() int { return p.age } func (p *Person) SetAge(age int) { p.age = age }
如何避免:
簡化方法名,避開get和set前綴,除非它們增加了方法的清晰性。
改進(jìn)后的例子:
type Person struct { name string Age int }
誤區(qū)五:在簡單轉(zhuǎn)發(fā)的getter/setter中添加鎖
在并發(fā)編程中,為了線程安全,可能會在getter和setter方法中添加鎖。然而,這有時候其實是一個過度設(shè)計。
例子:
type ThreadSafePerson struct { name string mu sync.Mutex } func (p *ThreadSafePerson) GetName() string { p.mu.Lock() defer p.mu.Unlock() return p.name } func (p *ThreadSafePerson) SetName(name string) { p.mu.Lock() defer p.mu.Unlock() p.name = name }
如何避免:
如果結(jié)構(gòu)體是immutable的或者很少修改,那么簡單的讀寫可能不需要鎖。考慮結(jié)構(gòu)體的使用場景,只在確實需要的時候加鎖。
改進(jìn)后的例子:
type ThreadSafePerson struct { Name string // Assume atomic or rarely changed fields }
總結(jié)
在Go中避免濫用getters和setters需要對Go的封裝原則有深入的理解。簡化你的API,保持方法直白,遵循Go的命名規(guī)范,這樣將讓你的代碼更加清晰和易于維護(hù)。
以上就是Go語言常見錯誤|之濫用getters/setters實例探究的詳細(xì)內(nèi)容,更多關(guān)于Go getters setters錯誤的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang gin 框架 異步同步 goroutine 并發(fā)操作
這篇文章主要介紹了golang gin 框架 異步同步 goroutine 并發(fā)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12Golang實現(xiàn)按行讀取文件的方法小結(jié)
按行讀取文件相較于一次性載入,有著很多優(yōu)勢,如內(nèi)存效率高、處理速度快、實時性高等,本文主要介紹了Golang按行讀取文件的相關(guān)方法,希望對大家有所幫助2024-02-02詳解Golang利用反射reflect動態(tài)調(diào)用方法
這篇文章主要介紹了詳解Golang利用反射reflect動態(tài)調(diào)用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11