英文:
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("content")
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("content")
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, "foo") // add to it
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论