如何在Go中实现可调整大小的数组

时间:2010-08-02 11:30:50

标签: go

我来自C ++背景,我习惯使用std::vector类来做这样的事情。 让我们假设我想要一个动态数组:

type a struct {
    b int
    c string
}

这样做的标准方法是什么?

一个片段非常有用

7 个答案:

答案 0 :(得分:56)

Go Slice包含三个元素:数据,长度和容量。

s := make([]int, 0, 10)

变量s是一个长度为0且容量为10的整数。内置的len()和cap()函数允许您获取切片的长度和容量:

len(s) == 0
cap(s) == 10

要增加切片的长度,只需重新切片:

s = s[0:5]
// len(s) == 5
// cap(s) == 10

要减小长度,可以采用子切片:

s = s[0:1]
// len(s) == 1

有一些较短的方法可以调用make():

a := make([]int, 10) 
// len(a) == cap(a) == 10

b := make([]int)
// len(b) == cap(b) == 0

这一切都很好,但是如果你需要增加切片的长度超出其容量呢?为此,您需要分配一个新切片并将旧切片的内容复制到新切片。 (“复制”功能是另一种内置功能。)

t := make([]int, len(s), 20)
copy(t, s)

Effective Go document进一步采用了这个例子,实现了一个Append函数,它将一个切片附加到另一个切片,并在必要时调整其大小。

切片由数组支持;当你使()一个特定容量的片段时,在后台分配该容量的数组。切片有效地成为该阵列的“智能指针”。如果将该切片(或该切片的子切片)传递给另一个函数,则将其作为指向同一数组的指针传递。这使得创建子片非常便宜 - 这是后备阵列的分配,这是非常昂贵的。

Go标准库包含许多容器包 - 例如vector - 无需手动管理切片。为了方便起见,使用切片来提高速度,并使用更复杂的容器类。 (说,我仍然在大多数情况下使用切片。)

您可能想知道为什么需要解决所有这些问题。毕竟,许多语言都提供动态调整大小的数组作为基元。其原因与Go的理念有关。语言设计者不会假设知道适合您的程序的分配策略是什么;相反,它们为您提供了构建自己的数据结构所需的工具。

答案 1 :(得分:53)

使用append()内置

示例:

type mytype struct {
  a, b int
}

func main() {
  a := []mytype{mytype{1, 2}, mytype{3, 4}}
  a = append(a, mytype{5, 6})
}

有关追加的更多信息,请参阅spec

答案 2 :(得分:18)

执行此操作的惯用方法已发生变化。 添加内置的append()函数意味着您可以像这样扩展切片:

type a struct {
    b int
    c string
}

func main(){
    var mySlice []a
    mySlice = append(mySlice,a{5,"pizza"})
}

如果有空间,Append()会将给定项目附加到切片,如果切片不够大,则将其扩展。

有关append()的更多信息,请访问http://golang.org/doc/go_spec.html#Appending_and_copying_slices

答案 3 :(得分:3)

有关内置append()简单示例

friends := []string{"Adam"}

friends = append(friends, "Rahul") // Add one friend or one string
        
friends = append(friends, "Angelica", "Rashi") // Add multiple friends or multiple strings

append() Documentation here

答案 4 :(得分:1)

您也可以使用切片。这是一个知道当前长度的数组。并且可以具有单独的电流长度和最大容量。请注意,为初始大小和容量传递的值不必是常量,因此您可以创建一个函数,该函数根据其参数构建和返回不同长度的切片。

好的一面是slice [] Int可以像数组一样被索引,并且在以这种方式使用时将返回int。

缺点是它不会自动增长其规定的容量。 Effective Go举例说明了如何处理重新分配。

代码将是

type mytype struct {
   a, b int
}




func main() {

  sl := make([]mytype, 10, 50) //slice of 10 items, max capacity 50 these do not have to be constant expressions.
  sl[0] = mytype{1,2}
   //...
  for i, value := range sl {
  // ... do stuff with value
  }
}

答案 5 :(得分:0)

嗨,我们可以简单地通过两种方式做到这一点

type mytype struct {
  a, b int
}

就这样吧

  1. 不附加

__

a := []mytype{mytype{1, 2}, mytype{3, 4}, mytype{4, 5}}
  1. 附上

__

a:=  append([]mytype{}, mytype{1, 2}, mytype{3, 4}, mytype{4, 5})

根据需要添加任意数量。第一个是执行此操作的简单方法。希望对您有帮助。

答案 6 :(得分:0)

如果你想在 Go 中有一个动态列表,那么你必须使用 Slice

您可以在此处了解更多信息: https://blog.golang.org/slices-intro

一些例子: https://tour.golang.org/moretypes/7 https://gobyexample.com/slices