是否可以使用golang创建一个动态清除结构实例值的方法?顺便说一句我是golang的新手.
type A struct {
Name string
Level int
}
type B struct {
Skill string
}
func main() {
a := A{"Momo", 1}
b := B{"Starfall"}
// outputs
// {"Momo", 1}
// {"Starfall"}
clear(a)
clear(b)
// outputs
// { , 0}
// { }
}
func clear(v interface{}) {
// some code
}
Run Code Online (Sandbox Code Playgroud)
Jim*_*imB 17
如果不传递指针,则无法修改原始值.
简单地在代码中分配新的零值会更容易也更清晰.如果类型更复杂,可以使用构造函数替换值,或者Reset()使用指针接收器为类型提供方法.
如果你真的想通过反射看看如何做到这一点你的clear功能可能如下:http://play.golang.org/p/g0zIzQA06b
func clear(v interface{}) {
p := reflect.ValueOf(v).Elem()
p.Set(reflect.Zero(p.Type()))
}
Run Code Online (Sandbox Code Playgroud)
(如果传入非指针值,这将会出现混乱)
尽管这个问题在 3 年零 9 个月前首次被问到,但 IMO 仍然没有一个好的答案,所以让我提出一个。
不需要反射,也不需要在每次想要清除变量时创建一个新实例。相反,您可以创建一个原始的新实例,将其保留在初始归零状态,然后您可以在需要时将其复制到对象的内存中Reset()。(向 @DaveC 致敬,因为他指出了一种Reset()更惯用的方法。)
您只需将归零值复制到对象使用指针指向的位置即可。以下内容为“将引用的内存值zeroA复制到引用的内存位置a。”:
*a = *zeroA
Run Code Online (Sandbox Code Playgroud)
这是我的完整示例,您也可以在Go Playground中尝试。(请注意,由于您的接收器是Reset()指向类型的指针A,因此调用该方法允许您更新在方法调用结束后更新仍然存在Reset()的值):a
package main
import (
"fmt"
)
type A struct {
Name string
Level int
}
var zeroA = &A{}
func (a *A) Reset() {
*a = *zeroA
}
func main() {
a1 := A{"Momo", 1}
a2 := &a1
a3 := a1
fmt.Println(a1)
fmt.Println(a2)
fmt.Println(a3)
a1.Reset()
fmt.Println(a1)
fmt.Println(a2)
fmt.Println(a3)
}
Run Code Online (Sandbox Code Playgroud)
这是你的输出(请注意,我证明你的变量已被清零,并且指向该变量的指针也被清零,但如果你制作了原始变量的*副本*,它不会被清零):
{Momo 1}
&{Momo 1}
{Momo 1}
{ 0}
&{ 0}
{Momo 1}
Run Code Online (Sandbox Code Playgroud)
您还可以使用此技术来复制包含默认值的结构的值。但请注意,这是浅复制,而不是深复制。如果您struct包含任何指针属性,则此方法也会复制指针值,并且不会分配内存来指向所指向值的新副本。因此,如果您想将结构重置为新的默认值,则需要做额外的工作Reset(),包括使用指针声明的任何子结构的副本。
我希望这对其他人有帮助,这样他们就不必像我一样经历艰难的过程来学习这一点。
您可以将其设置为空结构,如下所示:
var obj myStruct
obj.field1 = "apple"
obj.field2 = 12
// Reset struct.
obj = myStruct{}
Run Code Online (Sandbox Code Playgroud)
游乐场链接:https://play.golang.org/p/Rf1BqfFe3IQ