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)` 即可
留言
張貼留言