将一个指针设置为空接口。

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

Set a pointer to an empty interface

问题

我们正在使用openapi-generator来生成一个go-gin-server。这将生成包含类型为*interface{}的属性的模型,例如:

  1. type Material struct {
  2. Id *interface{} `json:"id,omitempty"`
  3. Reference *interface{} `json:"reference,omitempty"`
  4. }

如果我有一个这个结构体的实例,并且其中的指针为nil,如何设置它们呢?我尝试了以下方法:

  1. theReturnId := "abc123"
  2. material.Id = &theReturnId

这会导致编译错误:

无法将&theReturnId(类型为string的值)用作分配中的interface{}值:string未实现interface{}(*interface{}是指向接口的指针,而不是接口本身)

  1. theReturnId := "abc123"
  2. *material.Id = theReturnId

这会导致运行时错误,指针为nil。

我尝试了很多其他方法,但都没有成功。我在这里漏掉了什么?谢谢!

英文:

We are using the openapi-generator to generate a go-gin-server. This generates models containing properties of type *interface{} eg.

  1. type Material struct {
  2. Id *interface{} `json:"id,omitempty"`
  3. Reference *interface{} `json:"reference,omitempty"`
  4. }

If I have an instance of this struct, with nil pointers, how can these be set? I have tried the following:

  1. theReturnId := "abc123"
  2. material.Id = &theReturnId

This gives a compilation error of:

>cannot use &theReturnId (value of type *string) as *interface{} value in assignment: *string does not implement *interface{} (type interface{} is pointer to interface, not interface)

  1. theReturnId := "abc123"
  2. *material.Id = theReturnId

This gives a runtime error that the pointer is nil.

I have tried a bunch of other things but to no avail. What am I missing here? Thanks!

答案1

得分: 3

你几乎不需要指向接口的指针。你应该将接口作为值传递,但底层数据仍然可以是指针。

你需要重新考虑你的设计/代码生成技术,不要使用这种方法,因为它不符合 Go 的惯用方式。


如果你仍然想使用它,可以使用一个带类型的 interface{} 变量并取其地址。你在示例中的做法是错误的,因为 theReturnId 是一个字符串类型,取其地址意味着 *string 类型,它不能直接赋值给 *interface{} 类型,因为 Go 是一种强类型语言。

  1. package main
  2. import "fmt"
  3. type Material struct {
  4. Id *interface{} `json:"id,omitempty"`
  5. Reference *interface{} `json:"reference,omitempty"`
  6. }
  7. func main() {
  8. newMaterial := Material{}
  9. var foobar interface{} = "foobar"
  10. newMaterial.Id = &foobar
  11. fmt.Printf("%T\n", newMaterial.Id)
  12. }
英文:

You almost never need a pointer to an interface. You should be passing interfaces as values, but the underlying data though can still be a pointer.

You need to reconsider your design/code generation technique to not use such an approach as it is not idiomatic Go.


If you still want to use it, use a typed interface{} variable and take its address. The way you are doing in your example is incorrect as theReturnId is a string type taking its address would mean *string type, which cannot be assigned to *interface{} type directly as Go is a strongly typed language

  1. package main
  2. import "fmt"
  3. type Material struct {
  4. Id *interface{} `json:"id,omitempty"`
  5. Reference *interface{} `json:"reference,omitempty"`
  6. }
  7. func main() {
  8. newMaterial := Material{}
  9. var foobar interface{} = "foobar"
  10. newMaterial.Id = &foobar
  11. fmt.Printf("%T\n", newMaterial.Id)
  12. }

答案2

得分: 1

因为字段Id被设置为其零值,即nil,并且对其进行解引用(*material.Id)会导致运行时错误。你可以为Material编写一个构造函数,初始化其*interface{}字段:

  1. func NewMaterial() Material {
  2. return Material {
  3. new(interface{}),
  4. new(interface{}),
  5. }
  6. }

现在,你可以安全地解引用字段Id

  1. material := NewMaterial()
  2. theReturnId := "abc123"
  3. *material.Id = theReturnId
英文:

> theReturnId := "abc123"
> *material.Id = theReturnId
> This gives a runtime error that the pointer is nil.

Because the field Id is set to its zero value, i.e.: nil, and dereferencing it (*material.Id) results in a run-time error. You can write a constructor for Material that initializes its *interface{} fields:

  1. func NewMaterial() Material {
  2. return Material {
  3. new(interface{}),
  4. new(interface{}),
  5. }
  6. }

Now, you can safely dereference the field Id:

  1. material := NewMaterial()
  2. theReturnId := "abc123"
  3. *material.Id = theReturnId

huangapple
  • 本文由 发表于 2023年1月9日 01:52:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050104.html
匿名

发表评论

匿名网友

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

确定