加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

指针 – 在Golang中将接口设置为nil

发布时间:2020-12-16 09:26:18 所属栏目:大数据 来源:网络整理
导读:我正在尝试将接口的内部值设置为nil,如下所示: typ := TYP{InternalState: "filled"}setNil(typ)fmt.Printf("Expecting that %v to be nil",typ) 我需要知道如何实现setNil(typ interface {})方法. 有关详细信息see this code in play.golang.org. 解决方法
我正在尝试将接口的内部值设置为nil,如下所示:

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

fmt.Printf("Expecting that %v to be nil",typ)

我需要知道如何实现setNil(typ interface {})方法.

有关详细信息see this code in play.golang.org.

解决方法

问题是你没有接口值.你有一个指针值,一个指向具体类型的指针.这与界面值不同.

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

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

所以我们有2个不同/不同的案例:

nil接口的函数{}

func setNilIf(v *interface{}) {
    *v = nil
}

使用它:

var i interface{} = "Bob"
fmt.Printf("Before: %vn",i)
setNilIf(&i)
fmt.Printf("After: %vn",i)

输出:

Before: Bob
After: <nil>

所以它有效.

nil指针的函数;使用不安全

其实这是你的情况.我们想要改变指针类型变量的值.要接受指向任何类型的指针,我们可以使用unsafe.Pointer. unsafe.Pointer是language support,它是一种特殊的指针类型,可以从任何指针类型转换.

我们想接受指针变量的地址(指针),类似于** 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: %vn",typ)
setNilPtr(unsafe.Pointer(&typ))
fmt.Printf("After: %vn",typ)

输出:

Before: &{filled}
After: <nil>

所以这一个也有效.还有另一种使用反射的方法:

nil指针的函数;使用反射

您也可以仅使用反射(reflect包)来指定一个指针.我们仍然需要传递指针类型变量的地址.请注意,在这种情况下,参数的类型将只是接口{}.它将包含一个动态类型,如** SomeType.由于指针的值为零,我们可以使用Value.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: %vn",typ2)
setNilPtr2(&typ2)
fmt.Printf("After: %vn",typ2)

输出:

Before: &{filled}
After: <nil>

所以这一个也有效.请在Go Playground上试试这些.

但是说真的:如果你想要一些东西,请给它分配零.不要不必要地使事情复杂化.

i = nil
typ = nil

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读