我可以动态清除golang中类型结构的实例值吗?

jav*_*inc 14 struct go

是否可以使用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)

(如果传入非指针值,这将会出现混乱)


Mik*_*kel 7

尽管这个问题在 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(),包括使用指针声明的任何子结构的副本。

我希望这对其他人有帮助,这样他们就不必像我一样经历艰难的过程来学习这一点。


Flo*_*ish 5

您可以将其设置为空结构,如下所示:

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