dpylt7626401 2018-11-02 05:44
浏览 27

如何更有效地返回数组

My requirements is to have a function to return an array efficiently.

As I know, array is value type, so when passing in/out array to a function, it does copy. Therefore, I am thinking return pointer of array. People will recommend using slice, but by using slice, I still need copy to transfer to array.

This is the playground contains both solutions, please suggest if it is right way to go to return pointer of array, thanks.

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条回答 默认 最新

  • duangua5308 2018-11-02 06:45
    关注

    Arrays and Slices in Golang

    Most people who start to learn Go understand the concept of a slice. It's a lightweight wrapper around an array which can, but doesn't necessarily have to, represent a subset (or slice) of that underlying array. Despite this understanding, developers continue to get tripped up when putting that knowledge to practice. Why?

    The problem arises when you want to pass an array to a function. Go's documentation makes it clear that arrays are passed by copy. Useful perhaps, if you want the array to be immutable. In most cases though, it's simply an inefficiency. Initially, you might be tempted to do something like:

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

    That might set off your spidey sense. So you head off to the golang-nuts user group, read relevant posts, or maybe ask a question, and the answer you inevitably get back is: don't pass arrays, pass slices.

    That kinda fits with what you know, since slices are thin wrappers around arrays. But still, this only feels marginally better:

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

    You think to yourself, Who are these people who only ever deal with slices of arrays? 95% of the time, I need all the data in the array, not just part of it!

    And here, we get to the two fundamental misconceptions people have when they think about arrays and slices.

    First, think of a slices ability to represent part of the underlying array as a secondary benefit. First and foremost, a slice is a reference to an array. A slice which represents the entire array is extremely common. The second point makes this much more absolute.

    Second, you are almost certainly already dealing with a slice. names above, is already a slice (which covers the entire underlying array). The only time you're dealing with an array is when you create it with a size:

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

    Everything else, is a slice:

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

    So, the solution to the above code ends up being the most intuitive:

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

    Let's take this a step further and use this knowledge to clarify another common issue. Should you create an array of pointers. For example, which is better?

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

    In both cases, sayans is a slice. Therefore, when it comes to passing this to a function (or returning it), they are the same. Whether or not the extra indirection provided by the first example is useful depends on the situation, but if you aren't sure, it probably isn't, and you should be using the 2nd version.

    The two important points are:

    Slices are references to arrays which happen to have to ability to represent a subset, and Almost everything is already a slice

    评论

报告相同问题?

悬赏问题

  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决