Возврат ссылки на срез с использованием именованных возвращаемых значений в 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(). Каким будет правильный способ сделать это с помощью именованных возвращаемых значений, или это один из тех случаев, когда именованные возвращаемые значения не следует использовать? Объяснение, почему мое решение вызывает ошибку сегментации, очень приветствуется.

🤔 А знаете ли вы, что...
Go популярен для создания веб-серверов и микросервисов.


38
1

Ответ:

Решено

В объявлении возврата parsedBucketsNames *[]V2BucketAccess1 дается nil значение. Эта линия

*parsedBucketsNames = []V2BucketAccess{}

такой же как

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

Использование * для нулевого указателя приводит к сбою программы с нарушением сегментации. Вы не должны разыменовывать указатель так рано. Чтобы присвоить значение, вы должны получить адрес литерала

parsedBucketsNames = &[]V2BucketAccess{}

Я исправил ваш код здесь https://go.dev/play/p/AU5InoPWFJW