英文:
Set a pointer to an empty interface
问题
我们正在使用openapi-generator来生成一个go-gin-server。这将生成包含类型为*interface{}
的属性的模型,例如:
type Material struct {
Id *interface{} `json:"id,omitempty"`
Reference *interface{} `json:"reference,omitempty"`
}
如果我有一个这个结构体的实例,并且其中的指针为nil,如何设置它们呢?我尝试了以下方法:
theReturnId := "abc123"
material.Id = &theReturnId
这会导致编译错误:
无法将
&theReturnId
(类型为string的值)用作分配中的interface{}值:string未实现interface{}(*interface{}是指向接口的指针,而不是接口本身)
theReturnId := "abc123"
*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.
type Material struct {
Id *interface{} `json:"id,omitempty"`
Reference *interface{} `json:"reference,omitempty"`
}
If I have an instance of this struct, with nil pointers, how can these be set? I have tried the following:
theReturnId := "abc123"
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)
theReturnId := "abc123"
*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 是一种强类型语言。
package main
import "fmt"
type Material struct {
Id *interface{} `json:"id,omitempty"`
Reference *interface{} `json:"reference,omitempty"`
}
func main() {
newMaterial := Material{}
var foobar interface{} = "foobar"
newMaterial.Id = &foobar
fmt.Printf("%T\n", newMaterial.Id)
}
英文:
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
package main
import "fmt"
type Material struct {
Id *interface{} `json:"id,omitempty"`
Reference *interface{} `json:"reference,omitempty"`
}
func main() {
newMaterial := Material{}
var foobar interface{} = "foobar"
newMaterial.Id = &foobar
fmt.Printf("%T\n", newMaterial.Id)
}
答案2
得分: 1
因为字段Id
被设置为其零值,即nil
,并且对其进行解引用(*material.Id
)会导致运行时错误。你可以为Material
编写一个构造函数,初始化其*interface{}
字段:
func NewMaterial() Material {
return Material {
new(interface{}),
new(interface{}),
}
}
现在,你可以安全地解引用字段Id
:
material := NewMaterial()
theReturnId := "abc123"
*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:
func NewMaterial() Material {
return Material {
new(interface{}),
new(interface{}),
}
}
Now, you can safely dereference the field Id
:
material := NewMaterial()
theReturnId := "abc123"
*material.Id = theReturnId
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论