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

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.

A Go slice can't do that, but the append() function will grow your slice in a matter that appending elements becomes an O(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
}

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

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
}