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

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

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

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:

确定