如何更有效地返回数组

时间:2018-11-02 05:44:18

标签: go

我的要求是要有一个有效地返回数组的函数。

据我所知,数组是值类型,因此将数组传入/传出到函数时,它会执行copy。因此,我正在考虑数组的返回指针。人们会建议使用slice,但是通过使用slice,我仍然需要copy才能转移到数组。

the linked strtod documentation是包含两个解决方案的游乐场,请提出返回数组指针的正确方法,谢谢。

package main

import (
 "fmt"
)

type geo [2]float32

func genArray () geo {
  ret := geo{1.2, 2.3}
  return ret
}

func genPointerOfArray () *geo {
  ret := geo{1.2, 2.3}
  return &ret
}


func main() {
  ret1 := genArray()
  ret2 := *genPointerOfArray()
  fmt.Println(ret1, ret2)
}

1 个答案:

答案 0 :(得分:3)

Golang中的数组和切片

大多数开始学习Go的人都了解切片的概念。它是围绕数组的轻量级包装,它可以但不一定代表该基础数组的子集(或切片)。尽管有这种理解,开发人员在将这些知识付诸实践时仍会继续感到困惑。为什么?

当您要将数组传递给函数时,就会出现问题。 Go的文档清楚地表明,数组是通过副本传递的。如果您希望数组不可变,则可能有用。但是,在大多数情况下,这只是效率低下。最初,您可能会想做类似的事情:

names := []string{"leto", "paul", "teg"}
process(&names)

func process(names *[]string) {
  ...
}

这可能会引起您的间谍感。因此,您转到golang-nuts用户组,阅读相关文章,或者问一个问题,您不可避免地会得到以下答案:不要传递数组,传递切片。

这有点符合您所知道的,因为切片是数组周围的薄包装。但是,这仍然感觉好一点:

names := []string{"leto", "paul", "teg"}
process(names[0:])

func process(names []string) {
  ...
}

您自己想,这些只处理数组片段的人是谁? 95%的时间,我需要数组中的所有数据,而不仅仅是其中的一部分!

在这里,我们了解了人们在考虑数组和切片时存在的两个基本误解。

首先,将代表部分底层数组的切片功能视为次要优势。首先,切片是对数组的引用。代表整个数组的切片非常普遍。第二点使这一点更加绝对。

第二,您几乎肯定已经在处理切片了。上面的名称已经是一个切片(涵盖了整个基础数组)。处理数组的唯一时间是创建具有以下大小的数组:

  names := [3]string{"leto", "paul", "teg"}
  //or
  names := [3]string{}

其他所有东西都是切片:

  names := []string{"leto", "paul", "teg"}
  //or
  names := make([]string, 3)
  //or
  var names []string

因此,上述代码的解决方案最终是最直观的:

   names := []string{"leto", "paul", "teg"}
    process(names)

    func process(names []string) {
      ...
    }

让我们更进一步,并使用此知识来阐明另一个常见问题。您是否应该创建一个指针数组。例如,哪个更好?

  sayans := []*Sayan{
    &Sayan{Name: "Goku", Power: 9001,}
  }
  //or
  sayans := []Sayan{
    Sayan{Name: "Goku", Power: 9001,}
  }

在两种情况下,sayans都是片。因此,将其传递给函数(或返回它)时,它们是相同的。第一个示例提供的额外间接寻址是否有用取决于情况,但是如果您不确定,可能不是,并且应该使用第二个版本。

两个要点是:

  

切片是对数组的引用,这些数组恰好具有   代表一个子集,几乎所有内容都已经成为一个切片