把结构pointer转成interface{}后怎么转回来

Friz
南海鳄神 07月17日 字数 208

package main

import (

"fmt"

)

type dog struct {

Name string

}

func recv(intf interface{}) {

//how to get the &d value ?

}

func main() {

var d = dog{ Name: "Bolter"}

fmt.Printf("intf: %p\n", &d)

recv(&d)

}

Golang Go 编程语言
8 个回复
world
You are my world 07月17日

这个属于基础了。使用.(type)转换一下就行。

比如你的这个,fmt.Println(intf.(*dog).Name)

【 在 Friz (南海鳄神) 的大作中提到: 】

: package main

: import (

:     "fmt"

: ...................

Friz
南海鳄神 07月17日

转成dog是可以的,

但我发现如果我只是要&d这个对象的地址值,却怎么也搞不定, 还翻了reflect的实现

v := reflect.ValueOf(intf)

fmt.Printf("intf addr: %p\n", reflect.PtrTo(v.Type()))      //这里值不对

d := v.UnsafeAddr()  //这里panic了

当然如果把函数改成recv(p unsafe.Pointer),

用recv(unsafe.Pointer(&d))这样调用能搞定

但每次都是unsafe一下, 麻烦

【 在 world 的大作中提到: 】

: 这个属于基础了。使用.(type)转换一下就行。

: 比如你的这个,fmt.Println(intf.(*dog).Name)

world
You are my world 07月17日

地址值是啥意思。。

你先把interface转成*dog呗。

func recv(intf interface{}) {

fmt.Println(unsafe.Pointer(intf.(*dog)))

}

【 在 Friz (南海鳄神) 的大作中提到: 】

: 转成dog是可以的,

: 但我发现如果我只是要&d这个对象的地址值,却怎么也搞不定, 还翻了reflect的实现

: v := reflect.ValueOf(intf)

: ...................

Friz
南海鳄神 07月17日

recv函数需要和具体类型(dog)脱离, 因为还有可能其他类型,比如cat

recv需要做些组装, 只要取对象地址。

world
You are my world 07月17日

虽然还是不太明白你要做啥。。

不过你要坚持使用interface{}做参数的话,可以试试:

v := reflect.ValueOf(intf)

v.Pointer()来获取。

【 在 Friz (南海鳄神) 的大作中提到: 】

: recv函数需要和具体类型(dog)脱离, 因为还有可能其他类型,比如cat

: recv需要做些组装, 只要取对象地址。

flw
帅五进九 07月24日

你把问题说清楚喽,不说清楚没法帮你。

猜测你可以参考一下这个:

https://making.pusher.com/alternatives-to-sum-types-in-go/

【 在 Friz (南海鳄神) 的大作中提到: 】

: package main

: import (

:     "fmt"

: )

: type dog struct {

:    Name string

: }

: func recv(intf interface{}) {

:   //how to get the &d value ?

: }

: func main() {

:    var d = dog{ Name: "Bolter"}

:    fmt.Printf("intf: %p\n", &d)

:    recv(&d)

: }

shallowreg
07月29日

用c/c++思维写go了嘛?

shallowreg
09月16日

我也感觉这写go的思维不对,unsafe在生产环境从来没用过,

另外正真要用.(type)是要处理第二个参数的,或者使用switch方式,避免panic