Pointers 在Golang中将接口设置为nil

Pointers 在Golang中将接口设置为nil,pointers,go,reflection,interface,Pointers,Go,Reflection,Interface,我试图将接口的内部值设置为nil,如下所示: typ := &TYP{InternalState: "filled"} setNil(typ) fmt.Printf("Expecting that %v to be nil", typ) 我需要知道如何实现setNil(典型接口{})方法 了解更多详细信息。问题是您没有接口值。您有一个指针值,一个指向具体类型的指针。这与接口值不同 如果要更改任何类型变量的值,必须向其传递指针。这还包括接口类型的变量,以及指针类型的变量。当指向接口{}

我试图将接口的内部值设置为
nil
,如下所示:

typ := &TYP{InternalState: "filled"}
setNil(typ)

fmt.Printf("Expecting that %v to be nil", typ)
我需要知道如何实现
setNil(典型接口{})
方法


了解更多详细信息。

问题是您没有接口值。您有一个指针值,一个指向具体类型的指针。这与接口值不同

如果要更改任何类型变量的值,必须向其传递指针。这还包括接口类型的变量,以及指针类型的变量。当指向
接口{}
的指针有意义(
*接口{}
)时,这是非常罕见的情况之一,事实上这是不可避免的

但是如果您的函数需要一个接口,并且您传递了一个非接口值,那么将隐式创建一个接口值,并且您只能
nil
这个隐式创建的值

因此,我们有两种不同的情况:

函数设置为
nil
an
interface{}
使用它:

var i interface{} = "Bob"
fmt.Printf("Before: %v\n", i)
setNilIf(&i)
fmt.Printf("After: %v\n", i)
typ := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ)
setNilPtr(unsafe.Pointer(&typ))
fmt.Printf("After: %v\n", typ)
typ2 := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ2)
setNilPtr2(&typ2)
fmt.Printf("After: %v\n", typ2)
输出:

Before: Bob
After: <nil>
Before: &{filled}
After: <nil>
Before: &{filled}
After: <nil>
使用它:

var i interface{} = "Bob"
fmt.Printf("Before: %v\n", i)
setNilIf(&i)
fmt.Printf("After: %v\n", i)
typ := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ)
setNilPtr(unsafe.Pointer(&typ))
fmt.Printf("After: %v\n", typ)
typ2 := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ2)
setNilPtr2(&typ2)
fmt.Printf("After: %v\n", typ2)
输出:

Before: Bob
After: <nil>
Before: &{filled}
After: <nil>
Before: &{filled}
After: <nil>
使用它:

var i interface{} = "Bob"
fmt.Printf("Before: %v\n", i)
setNilIf(&i)
fmt.Printf("After: %v\n", i)
typ := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ)
setNilPtr(unsafe.Pointer(&typ))
fmt.Printf("After: %v\n", typ)
typ2 := &TYP{InternalState: "filled"}
fmt.Printf("Before: %v\n", typ2)
setNilPtr2(&typ2)
fmt.Printf("After: %v\n", typ2)
输出:

Before: Bob
After: <nil>
Before: &{filled}
After: <nil>
Before: &{filled}
After: <nil>

但是为什么呢?“你不能使用布尔值。@yene:我喜欢保持界面设计的简洁。如果不直接从函数返回
nil
,我看不出这是怎么做到的。”。例如,想想
setNil(3)
。谢谢icza,但我想避免我的客户端知道
不安全的指针,我不想让我的客户端以
*接口{}
的形式传递类型。那么你能做到这一点吗?=>@Mohsen请看编辑后的答案。我添加了第三种方法,只在函数内部使用反射。你必须传递变量的地址,这是不可避免的,但是这个变量没有使用
不安全的指针
:Thx非常icza,但是我必须,看看:(为什么不使用泛型!):-)