在Golang中使用命名返回值返回切片的引用。

huangapple go评论76阅读模式
英文:

returning a reference to a slice using named return values in Golang

问题

我有这段代码,它返回一个切片的引用:

package main

import "fmt"

type V2BucketAccess struct {
	BucketName   string
	AccessPolicy string
}

func main() {
	result := MyFunc()
	fmt.Print(*result)
}

func MyFunc() *[]V2BucketAccess {
	parsedBucketsNames := []V2BucketAccess{}
	mystuff1 := V2BucketAccess{
		BucketName:   "bucket-1",
		AccessPolicy: "readwrite",
	}
	mystuff2 := V2BucketAccess{
		BucketName:   "bucket-2",
		AccessPolicy: "read",
	}
	parsedBucketsNames = append(parsedBucketsNames, mystuff1, mystuff2)
	return &parsedBucketsNames
}

我想使用命名返回值重写它,我想到了以下代码:

package main

import "fmt"

type V2BucketAccess struct {
	BucketName   string
	AccessPolicy string
}

func main() {
	result := MyFunc()
	fmt.Print(*result)
}

func MyFunc() (parsedBucketsNames *[]V2BucketAccess) {
	*parsedBucketsNames = []V2BucketAccess{}
	mystuff1 := V2BucketAccess{
		BucketName:   "bucket-1",
		AccessPolicy: "readwrite",
	}
	mystuff2 := V2BucketAccess{
		BucketName:   "bucket-2",
		AccessPolicy: "read",
	}
	*parsedBucketsNames = append(*parsedBucketsNames, mystuff1, mystuff2)
	return
}

然而,这会在MyFunc()函数的第一行生成一个分段错误。使用命名返回值的正确方法是什么,或者这是那种不应该使用命名返回值的情况之一?对于为什么我的解决方案会生成分段错误的解释将非常受欢迎。

英文:

I have this piece of code, which returns a reference to a slice:

package main

import "fmt"

type V2BucketAccess struct {
	BucketName   string
	AccessPolicy string
}

func main() {
	result := MyFunc()
	fmt.Print(*result)
}

func MyFunc() *[]V2BucketAccess {
	parsedBucketsNames := []V2BucketAccess{}
	mystuff1 := V2BucketAccess{
		BucketName:   "bucket-1",
		AccessPolicy: "readwrite",
	}
	mystuff2 := V2BucketAccess{
		BucketName:   "bucket-2",
		AccessPolicy: "read",
	}
	parsedBucketsNames = append(parsedBucketsNames, mystuff1, mystuff2)
	return &parsedBucketsNames
}

I wanted to rewrite this using named return values, and I came up with something like this:

package main

import "fmt"

type V2BucketAccess struct {
	BucketName   string
	AccessPolicy string
}

func main() {
	result := MyFunc()
	fmt.Print(*result)
}

func MyFunc() (parsedBucketsNames *[]V2BucketAccess) {
	*parsedBucketsNames = []V2BucketAccess{}
	mystuff1 := V2BucketAccess{
		BucketName:   "bucket-1",
		AccessPolicy: "readwrite",
	}
	mystuff2 := V2BucketAccess{
		BucketName:   "bucket-2",
		AccessPolicy: "read",
	}
	*parsedBucketsNames = append(*parsedBucketsNames, mystuff1, mystuff2)
	return
}

However, this generates a segmentation violation on the first line of the MyFunc() function. What would be the correct way to do this via named return values, or is this one of those cases where named return values shouldn't be used? An explanation why my solution generates a segmentation fault is very welcome.

答案1

得分: 1

在返回声明中,parsedBucketsNames *[]V2BucketAccess1 被赋予了 nil 值。这行代码

*parsedBucketsNames = []V2BucketAccess{}

与下面的代码是等价的

var parsedBucketsNames *[]V2BucketAccess
*parsedBucketsNames = []V2BucketAccess{}

在一个空指针上使用 * 会导致程序崩溃并出现分段错误。你不应该这么早地解引用指针。要赋值,你必须获取字面量的地址

parsedBucketsNames = &[]V2BucketAccess{}

我在这里修复了你的代码:https://go.dev/play/p/AU5InoPWFJW

英文:

In return declaration parsedBucketsNames *[]V2BucketAccess1 is given nil value. This line

*parsedBucketsNames = []V2BucketAccess{}

is the same as

var parsedBucketsNames *[]V2BucketAccess
*parsedBucketsNames = []V2BucketAccess{}

Using * on a nil pointer makes the program crash with segmentation violation. You must not dereference the pointer so early. To assign a value you must obtain the address of the literal

parsedBucketsNames = &[]V2BucketAccess{}

I fixed your code here https://go.dev/play/p/AU5InoPWFJW

huangapple
  • 本文由 发表于 2022年5月16日 22:58:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/72261289.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定