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

Issue

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.

Solution

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

Answered By – Marco Järvinen

Answer Checked By – Marie Seifert (GoLangFix Admin)

Leave a Reply

Your email address will not be published.