如何更有效地返回数组

Ron*_*Ron 1 go

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

据我所知,数组是值类型,因此当将输入/输出数组传递给函数时,它会这样做copy。因此,我正在考虑数组的返回指针。人们会推荐使用切片,但是通过使用切片,我仍然需要copy转移到数组。

是游乐场包含两种解决方案,请建议返回数组指针是否是正确的方法,谢谢。

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)
}
Run Code Online (Sandbox Code Playgroud)

ASH*_*EEV 8

Golang 中的数组和切片

大多数开始学习 Go 的人都了解切片的概念。它是数组的轻量级包装器,可以但不一定必须表示底层数组的子集(或切片)。尽管有这样的理解,开发人员在将这些知识付诸实践时仍然会遇到困难。为什么?

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

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

func process(names *[]string) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

这可能会激发你的蜘蛛侠意识。因此,您前往 golang-nuts 用户组,阅读相关帖子,或者提出问题,您不可避免地得到的答案是:不要传递数组,而是传递切片。

这有点符合你所知道的,因为切片是数组的薄包装。但尽管如此,这只是感觉好一点:

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

func process(names []string) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

您心想,这些只处理数组切片的人是谁?95% 的情况下,我需要数组中的所有数据,而不仅仅是其中的一部分!

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

首先,将切片表示部分底层数组的能力视为次要好处。首先也是最重要的,切片是对数组的引用。代表整个数组的切片非常常见。第二点使这一点更加绝对。

其次,几乎可以肯定您已经在处理切片了。上面的名称已经是一个切片(覆盖整个底层数组)。唯一一次处理数组是在创建具有大小的数组时:

  names := [3]string{"leto", "paul", "teg"}
  //or
  names := [3]string{}
Run Code Online (Sandbox Code Playgroud)

其他一切都是一个切片:

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

所以,上面代码的解决方案最终是最直观的:

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

    func process(names []string) {
      ...
    }
Run Code Online (Sandbox Code Playgroud)

让我们更进一步,利用这些知识来澄清另一个常见问题。你应该创建一个指针数组吗?例如,哪个更好?

  sayans := []*Sayan{
    &Sayan{Name: "Goku", Power: 9001,}
  }
  //or
  sayans := []Sayan{
    Sayan{Name: "Goku", Power: 9001,}
  }
Run Code Online (Sandbox Code Playgroud)

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

两个要点是:

切片是对数组的引用,数组恰好能够表示子集,并且几乎所有内容都已经是切片