【问题标题】:Clearing and rewriting slice in loop在循环中清除和重写切片
【发布时间】:2018-08-21 23:42:10
【问题描述】:

我想知道在我的用例中删除切片的“最”正确方法是什么。我有一个 for 循环,我可以在其中运行它返回一个切片,然后将该切片附加到一个更大的切片上。每次调用 for 循环时,较小的切片应该是空的。我不能只用返回的值覆盖切片,因为我需要知道长度。

我得到了预期的输出,但不知道我是否会遇到内存泄漏或获取错误数据的错误。 最好将切片设置为 nil、制作新切片还是其他方式?

https://play.golang.org/p/JxMKaFQAPWL

package main

import (
    "fmt"
)

func populateSlice(offset int) []string {
    letters := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "OP", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
    toReturn := make([]string, 0)

    if len(letters)-offset <= 0 {
        toReturn = nil
    } else if len(letters) < offset+10 {
        remaining := len(letters) - offset
        toReturn = letters[offset:remaining+offset]
    } else {
        toReturn = letters[offset:10+offset]
    }

    fmt.Printf("toReturn: %#v\n", toReturn)
    return toReturn

}

func main() {

    offset := 0
    bigSlice := make([]string, 0)

    for {

        smallSlice := populateSlice(offset)

        bigSlice = append(bigSlice, smallSlice...)

        if smallSlice == nil || len(smallSlice) < 5 {
            fmt.Printf("break: len(smallSlice): %v", len(smallSlice))
            break
        }
        offset += len(smallSlice)

        fmt.Printf("smallSlice: %#v\n", smallSlice)
        fmt.Printf("bigSlice: %#v\n\n", bigSlice)
    }
}

【问题讨论】:

    标签: go slice


    【解决方案1】:

    首先,简化您的代码,

    package main
    
    import "fmt"
    
    func populateSlice(offset int) []string {
        letters := []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "OP", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
        lo, hi := offset, offset+10
        if hi > len(letters) {
            hi = len(letters)
        }
        if lo < 0 || lo >= hi {
            return nil
        }
        return letters[lo:hi:hi]
    }
    
    func main() {
        var bigSlice []string
        for offset := 0; ; {
            smallSlice := populateSlice(offset)
            fmt.Printf("smallSlice: %#v\n", smallSlice)
            if len(smallSlice) == 0 {
                break
            }
            bigSlice = append(bigSlice, smallSlice...)
            offset += len(smallSlice)
        }
        bigSlice = bigSlice[:len(bigSlice):len(bigSlice)]
        fmt.Printf("bigSlice: %#v\n", bigSlice)
    }
    

    游乐场:https://play.golang.org/p/sRqazV_luol

    输出:

    smallSlice: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}
    smallSlice: []string{"k", "l", "m", "n", "OP", "q", "r", "s", "t", "u"}
    smallSlice: []string{"v", "w", "x", "y", "z"}
    smallSlice: []string(nil)
    bigSlice: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "OP", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
    

    没有要删除的切片。没有内存泄漏。 Go 有一个垃圾收集器。没有不良数据。

    【讨论】:

      猜你喜欢
      • 2013-09-26
      • 2018-12-20
      • 2016-07-03
      • 2018-06-21
      • 2021-03-28
      • 2020-03-26
      • 2020-12-18
      • 2013-06-03
      • 1970-01-01
      相关资源
      最近更新 更多