摘要:在 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/
来源:子骞教育
免责声明:本站系转载,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本站联系,我们将在第一时间删除内容!