在Go中获取常量的指针

摘要:在 Go 中,有时你需要获取一个常量值的指针。通常情况下,这很简单,但前提是你拥有的是一个值,而不是常量。例如,当你或你的同事在使用 aws S3 API 时,可能需要将某个值传递给某个参数:

在 Go 中,有时你需要获取一个常量值的指针。通常情况下,这很简单,但前提是你拥有的是一个值,而不是常量。例如,当你或你的同事在使用 aws S3 API 时,可能需要将某个值传递给某个参数:

_, err = s3c.PutObject(ctx, &s3.PutObjectInput{Bucket: "mah-bukkit",Key: "something",Body: bytes.NewReader(fileContent),})

这段代码会导致编译错误,因为你需要传递的是字符串的指针。

这里有几种解决办法,我将按从最不“奇技淫巧”到最“奇技淫巧”的顺序进行说明。

你可以对变量取指针,但不能对常量取指针。将 Bucket 和 Key 提升为变量:

bucketName := "mah-bukkit"key := "something"_, err = s3c.PutObject(ctx, &s3.PutObjectInput{Bucket: &bucketName,Key: &key,Body: bytes.NewReader(fileContent),})

这在大多数情况下是可行的,但每次都需要声明变量,这看起来可能有些奇怪。

aws 包提供了一些辅助函数来完成这种转换。以下是示例代码:

_, err = s3c.PutObject(ctx, &s3.PutObjectInput{Bucket: aws.String("mah-bukkit"),Key: aws.String("something"),Body: bytes.NewReader(fileContent),})

这是因为函数参数会被当作值处理,aws.String 的实现类似于:

package awsfunc String(val string) *string {return &val}

你还可以使用 Go 泛型实现一个通用的“获取指针”函数:

func p[T any](val T) *T {return &val}

然后可以正常使用:

_, err = s3c.PutObject(ctx, &s3.PutObjectInput{Bucket: p("mah-bukkit"),Key: p("something"),Body: bytes.NewReader(fileContent),})raised := &string{"foo"}[0]

它的原理是创建一个匿名的字符串切片,切片中包含一个成员 foo,然后取出这个切片的第一个元素,并获取它的指针。虽然这种写法看起来有点“邪门”:

_, err = s3c.PutObject(ctx, &s3.PutObjectInput{Bucket: &string{"mah-bukkit"}[0],Key: &string{"something"}[0],Body: bytes.NewReader(fileContent),})

但每一步操作都是完全符合逻辑的。

翻译自https://xeiaso.net/notes/2024/go-pointer-constant/

来源:子骞教育

相关推荐