Slice沒照預期的切片

markdown
## 結論 在使用make初始化slice的時候,要考慮初始的長度,若是只用兩個參數會使長度等於容量,也就是已經初始化過了,這時再用append的話就不會如想像那樣從頭開始新增資料了! ## 環境 go v1.19.6 ```go type Card struct { Word string Explain string } ``` ## 預期的對照組 * 這是正常運行的 ```go stackB := []Card{ { Word: "test", Explain: "test", }, { Word: "test2", Explain: "test2", }, { Word: "test3", Explain: "test3", }, } fmt.Println(stackB) // worked stackB = stackB[:2] fmt.Println(stackB) // worked ``` ## 非預期的狀況 ```go stack, _ := GetCardMap() fmt.Println(stack) // worked stack = stack[:2] fmt.Println(stack) // only 2 empty element func GetCardMap() (m []Card, err error) { file, err := os.Open("frequecydic.txt") if err != nil { return nil, err } defer file.Close() totalCount, err := VerifyDic(file) if err != nil { return nil, err } // move file pointer to the beginning of file _, err = file.Seek(0, io.SeekStart) if err != nil { return nil, err } m = make([]Card, totalCount) scanner := bufio.NewScanner(file) for scanner.Scan() { v := strings.SplitN(scanner.Text(), " ", 2) c := Card{ Word: v[0], Explain: v[1], } m = append(m, c) } return m, nil } func VerifyDic(file *os.File) (count int, err error) { errMsg := "" count = 0 scanner := bufio.NewScanner(file) for scanner.Scan() { count++ v := strings.SplitN(scanner.Text(), " ", 2) if len(v) != 2 { errMsg += fmt.Sprintf("invalid line[%d]: %s\n", count, scanner.Text()) } } if err := scanner.Err(); err != nil { errMsg += err.Error() } if errMsg != "" { return count, fmt.Errorf(errMsg) } return count, nil } ``` ## 解決 ==為什麼給定容量反而無法切片呢?== 看起來也不像是擴容的關系。 在dbug之後發現因為使用的是: ``` m = make([]Card, totalCount) // 只用兩個參數,因此陣例初始化是一堆空值 m = append(m, c) // 加在最後面,所以前面都是空值 ``` * 將`make([]Card, totalCount)`改成 `make([]Card, 0, totalCount)` 即可

留言

這個網誌中的熱門文章

成人剪舌繫帶聽過嗎?我剪了!!

Scp - ssh 的遠端檔案傳輸指令

睡覺使你更有效率