如何在Golang中创建一个长度不固定的切片?

huangapple go评论73阅读模式
英文:

how to create a unfixed length slice in golang

问题

有没有办法在Go中创建一个长度不固定的切片?例如,我想获取目录(content/)中的所有文件名,并填充到一个[]string切片中。

content/目录包含以下内容:

$-> tree content/
content/
├── 1.txt
├── 2.txt
└── tmp

这是我目前的代码:

package main

import (
    "fmt"
    "io/ioutil"
)

func listFile() []string {
    list := make([]string, 100)
    // 如你所见,我创建了一个长度为100的切片,但这并不合适。

    files, _ := ioutil.ReadDir("content")
    i := 0
    for _, f := range files{
        list[i] = f.Name()
        i = i+1
    }
    return list
}

func main(){
    fmt.Print(listFile())
}

我想要实现的是模拟Java中的ArrayList的行为,我可以简单地使用list.add(),而不用担心长度。

Go语言中的切片能做到这一点吗?

谢谢。

英文:

Is there any way to create a unfixed length slice in go? As a example, I want to grab all the fileNames in a directory(content/) fill to a [] string slice.

The content/ dir contains:

$-> tree content/
content/
├── 1.txt
├── 2.txt
└── tmp

Here is what I currently got:

package main

import (
    "fmt"
    "io/ioutil"
)

func listFile() []string {
    list := make([]string, 100)
    // as you can see, I make a slice length as 100, but that is not appropriate.
    
    files, _ := ioutil.ReadDir("content")
    i := 0
    for _, f := range files{
        list[i] = f.Name()
        i = i+1
    }
    return list
}

func main(){
    fmt.Print(listFile())
}

What I want to achieve is a way to simulate the behavior of ArrayList in java, which I can just simply list.add() and wont care about the length.

Can slice in GoLang do that?

Thanks.

答案1

得分: 5

一个Go切片无法做到这一点,但append()函数可以以一种使得追加元素成为O(1)摊销操作的方式来扩展切片:

func listFile() []string {
    // 创建长度为0的切片
    list := make([]string, 0)

    files, _ := ioutil.ReadDir("content")
    for _, f := range files {
        // 根据需要扩展切片
        list = append(list, f.Name())
    }

    return list
}
英文:

A Go slice can't do that, but the append() function will grow your slice in a matter that appending elements becomes an <i>O</i>(1) amortized operation:

func listFile() []string {
    // make a slice of length 0
    list := make([]string, 0)

    files, _ := ioutil.ReadDir(&quot;content&quot;)
    for _, f := range files {
        // append grows list as needed
        list = append(list, f.Name())
    }

    return list
}

答案2

得分: 2

要从FileInfo的切片中生成一个名称的切片,你不需要像Java的ArrayList那样的东西。

ioutil.ReadDir()会返回一个FileInfo的切片,你可以使用内置的**len**函数查询其长度:

count := len(files)

因此,你可以创建一个能够容纳这么多名称的数组或切片:

func listFile() []string {
    files, _ := ioutil.ReadDir("content")

    list := make([]string, len(files))
    for i, f := range files {
        list[i] = f.Name()
    }

    return list
}
英文:

To produce a slice of names from a slice of FileInfo, you don't need anything like the Java ArrayList.

ioutil.ReadDir() returns you a slice of FileInfo of which you can query its length using the built-in len function:

count := len(files)

So you you can make an array or slice capable of holding names of this amount:

func listFile() []string {
	files, _ := ioutil.ReadDir(&quot;content&quot;)

	list := make([]string, len(files))
	for i, f := range files {
		list[i] = f.Name()
	}

	return list
}

答案3

得分: 1

是的,你可以创建一个空的切片,并使用append方法向其添加元素。如果你大致知道预期的平均大小,你可以为其预留一些空间,就像Java中的ArrayList一样。这样可以避免在切片增长时重新分配底层数据。

// 创建一个空的切片,并预留20个元素的空间以避免重新分配
list := make([]string, 0, 20)

// 现在我们可以向其中添加元素,底层数据不会被复制
list = append(list, "foo") // 添加元素
英文:

Yes, you can create an empty slice and append to it with append. If you know more or less the average size you're expecting, you can reserve some space for it, just like in Java's ArrayList. This will prevent reallocating the underlying data when the slice grows.

//make an empty slice with 20 reserved items to avoid 
list := make([]string, 0, 20)reallocation

// now we just append to it. The underlying data is not copied
list = append(list, &quot;foo&quot;) // add to it

huangapple
  • 本文由 发表于 2015年1月6日 14:20:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/27793165.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定