如何动态清除类型结构实例的值

How to clear values of a instance of a type struct dynamically

是否可以使用 Go 创建一个动态清除结构实例值的方法?

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
}

如果不传递指向原始值的指针,则无法修改它们。

在您的代码中简单地分配一个新的零值会更容易、更清晰。如果你的类型更复杂,你可以用构造函数替换值,或者为你的类型提供 Reset() 方法和指针接收器。

如果你真的想看看如何通过反射来实现它,你的 clear 函数可能如下所示:http://play.golang.org/p/g0zIzQA06b

func clear(v interface{}) {
    p := reflect.ValueOf(v).Elem()
    p.Set(reflect.Zero(p.Type()))
}

(如果你传入一个非指针值,这会造成恐慌)

可以使用将重置值的结构的空对象重新分配值。

a := A{"Momo", 1}
b := B{"Starfall"}

fmt.Println(a)
fmt.Println(b)
// outputs
// {"Momo", 1}
// {"Starfall"}

a = A{}
b = B{}
// outputs
// { , 0}
// { }

https://play.golang.org/p/CJ6cx2TFytY

尽管这个问题是在 3 年零 9 个月前首次提出的,但 IMO 仍然没有一个好的答案,所以让我提出一个。

不需要反射,也不需要每次要清除变量时都创建一个新实例。相反,创建一个原始的新实例,您将其保留在其初始归零状态,然后您可以在需要 Reset() 时复制对象的内存。 (向@DaveC 致敬,指出 Reset() 方法更为惯用。)

您只需使用指针从归零值复制到对象指向的位置。下面写"Copy the value of the memory that zeroA references to the memory location that a references.":

*a = *zeroA

这是我的完整示例,您也可以在 the Go Playground. (Note that since your receiver 中尝试,因为 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)
}

这是你的输出 (请注意,我证明你的变量已清零,指向该变量的指针也已清零,但如果你制作了原始文件的*副本*,则不会归零):

{Momo 1}
&{Momo 1}
{Momo 1}
{ 0}
&{ 0}
{Momo 1}    

您还可以使用此技术复制包含默认值的结构的值。 但是请注意,这是一个浅拷贝,而不是深拷贝。如果您的 struct 包含任何指针属性,此方法也会复制指针值,并且不会分配内存以指向所指向值的新副本。因此,如果您想将结构重置为新的默认值,包括使用指针声明的任何子结构的副本,您将需要在 Reset() 中做额外的工作。

我希望这对其他人有帮助,这样他们就不必像我一样费力地学习它。

您可以像这样将它设置为空结构:

var obj myStruct
obj.field1 = "apple"
obj.field2 = 12

// Reset struct.
obj = myStruct{}

游乐场link:https://play.golang.org/p/Rf1BqfFe3IQ