如果要更改任何类型的变量的值,则必须将指针传递给它.这还包括接口类型的变量,以及指针类型的变量.当接口{}的指针有意义时(* interface {}),这是非常罕见的情况之一,实际上它是不可避免的.
但是,如果您的函数需要一个接口并且您传递了一个非接口值,那么将隐式创建一个接口值,您只能忽略这个隐式创建的值.
所以我们有2个不同/不同的案例:
nil接口的函数{}
func setNilIf(v *interface{}) { *v = nil }
使用它:
var i interface{} = "Bob" fmt.Printf("Before: %v\n",i) setNilIf(&i) fmt.Printf("After: %v\n",i)
Before: Bob After: <nil>
所以它有效.
nil指针的函数;使用不安全
unsafe.Pointer
我们想接受指针变量的地址(指针),类似于** SomeType.为了能够为指针变量分配新值(nil),我们必须取消引用它(*运算符).但是unsafe.Pointer不能被解除引用,所以首先我们必须将它转换为指向“something”的指针,但是因为我们只想指定nil(对于所有指针类型都是相同的,不管指向的值的类型如何),“东西”没关系,我只会使用int,所以我将unsafe.Pointer指针值转换为** int.
func setNilPtr(p unsafe.Pointer) { *(**int)(p) = nil }
使用它:
typ := &TYP{InternalState: "filled"} fmt.Printf("Before: %v\n",typ) setNilPtr(unsafe.Pointer(&typ)) fmt.Printf("After: %v\n",typ)
Before: &{filleD} After: <nil>
所以这一个也有效.还有另一种使用反射的方法:
nil指针的函数;使用反射
reflectValue.Set()Value.Set()
func setNilPtr2(i interface{}) { v := reflect.ValueOf(i) v.Elem().Set(reflect.Zero(v.Elem().Type())) }
使用它:
typ2 := &TYP{InternalState: "filled"} fmt.Printf("Before: %v\n",typ2) setNilPtr2(&typ2) fmt.Printf("After: %v\n",typ2)
Before: &{filleD} After: <nil>
所以这一个也有效.请在Go Playground上试试这些.
但是说真的:如果你想要一些东西,请给它分配零.不要不必要地使事情复杂化.
i = nil typ = nil