您好,登錄后才能下訂單哦!
這篇文章主要介紹“Go開發(fā)中的常見錯誤有哪些”,在日常操作中,相信很多人在Go開發(fā)中的常見錯誤有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Go開發(fā)中的常見錯誤有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
遞歸調用自身的函數(shù)需要有一個退出條件。否則,它將永遠遞歸,直到系統(tǒng)內存耗盡。
此問題可能是由常見錯誤引起的,例如忘記添加退出條件。它也可能“故意”發(fā)生。某些語言具有尾調用優(yōu)化,這使得某些無限遞歸調用可以安全使用。尾調用優(yōu)化允許您避免為函數(shù)分配新的堆棧幀,因為調用函數(shù)將返回它從被調用函數(shù)獲取的值。最常見的用途是尾遞歸,其中為利用尾調用優(yōu)化而編寫的遞歸函數(shù)可以使用常量堆??臻g。然而,Go 并沒有實現(xiàn)尾調用優(yōu)化,你最終會耗盡內存。然而,這個問題不適用于產生新的 goroutine。
在添加任何元素之前,需要使用make函數(shù)(或map文字)初始化映射。使用內置函數(shù)創(chuàng)建一個新的空映射值make,該函數(shù)將map類型和可選的容量提示作為參數(shù):
make(map[string]int)
make(map[string]int, 100)
初始容量不限制其大?。旱貓D增長以容納存儲在其中的項目數(shù)量,nil
地圖除外。甲nil
地圖相當于不同之處在于可以添加沒有元素的空映射。
不好的模式:
var countedData map[string][]ChartElement
好的模式:
countedData := make(map[string][]ChartElement)
修改非指針接收器值的方法可能會產生不良后果。這是一個錯誤風險,因為該方法可能會更改方法內部接收器的值,但不會反映在原始值中。要傳播更改,接收者必須是一個指針。
例如:
type data struct {
num int
key *string
items map[string]bool
}
func (d data) vmethod() {
d.num = 8
}
func (d data) run() {
d.vmethod()
fmt.Printf("%+v", d) // Output: {num:1 key:0xc0000961e0 items:map[1:true]}
}
如果num
必須修改:
type data struct {
num int
key *string
items map[string]bool
}
func (d *data) vmethod() {
d.num = 8
}
func (d *data) run() {
d.vmethod()
fmt.Printf("%+v", d) // Output: &{num:8 key:0xc00010a040 items:map[1:true]}
}
循環(huán)中的范圍變量在每次迭代中都被重用;因此,在循環(huán)中創(chuàng)建的 goroutine 將指向上作用域的范圍變量。這樣,goroutine 就可以使用帶有不需要的值的變量。
在下面的示例中,goroutine 中使用的 index 和 value 的值來自外部范圍。因為 goroutine 是異步運行的,所以 index 和 value 的值可能(通常是)與預期值不同。
mySlice := []string{"A", "B", "C"}
for index, value := range mySlice {
go func() {
fmt.Printf("Index: %d\n", index)
fmt.Printf("Value: %s\n", value)
}()
}
為了克服這個問題,必須創(chuàng)建一個本地作用域,如下例所示。
mySlice := []string{"A", "B", "C"}
for index, value := range mySlice {
index := index
value := value
go func() {
fmt.Printf("Index: %d\n", index)
fmt.Printf("Value: %s\n", value)
}()
}
處理此問題的另一種方法是將值作為 args 傳遞給 goroutine。
mySlice := []string{"A", "B", "C"}
for index, value := range mySlice {
go func(index int, value string) {
fmt.Printf("Index: %d\n", index)
fmt.Printf("Value: %s\n", value)
}(index, value)
}
對于實現(xiàn)接口的值defer的Close()方法,這是 Go 開發(fā)人員的常見模式io.Closer。例如,打開文件時:
f, err := os.Open("/tmp/file.md")
if err != nil {
return err
}
defer f.Close()
但是這種模式對于可寫文件是有害的,因為推遲函數(shù)調用會忽略其返回值,并且該Close()方法可能會返回錯誤。例如,如果您將數(shù)據(jù)寫入文件,則在您調用Close. 應明確處理此錯誤。
雖然您可以在不使用的情況下繼續(xù),但defer您需要記住每次完成工作時關閉文件。更好的方法是defer使用包裝函數(shù),如下例所示。
f, err := os.Open("/tmp/file.md")
if err != nil {
return err
}
defer func() {
closeErr := f.Close()
if closeErr != nil {
if err == nil {
err = closeErr
} else {
log.Println("Error occured while closing the file :", closeErr)
}
}
}()
return err
在團隊中工作時,審查其他人的代碼變得很重要。DeepSource是一種自動化代碼審查工具,可管理端到端代碼掃描過程,并在推送新提交或新拉取請求時自動發(fā)出帶有修復的拉取請求。
為 Go 設置 DeepSource非常簡單。一旦設置完成,將對整個代碼庫執(zhí)行初始掃描,找到改進的范圍,修復它們,并為這些更改打開 PR。
到此,關于“Go開發(fā)中的常見錯誤有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。