英文:
Golang - Get a pointer to a field of a struct through an interface
问题
我正在非常早期的了解Go语言中的接口。我正在编写一些逻辑模拟,并有以下类似的代码(这里我进行了大量简化):
请参考我的问题的注释:
type LogicNode struct {
Input *bool
Output *bool
Operator string
Next Node
}
func (n *LogicNode) Run() {
// 在这里做一些事情
n.Next.Run()
}
type Node interface {
Run()
}
func main() {
nodes := make([]Node, 1000)
for i := 0; i < 1000; i++ {
n := LogicNode{
// 分配值等等。
}
nodes[i] = &n
}
for i, node := range nodes {
// 我需要在这里访问LogicNode的Output指针,作为*bool类型。
// 这样我就可以将相同的地址设置给其他Node的Input,从而"连接"它们。
// 但是我只能得到类似这样的东西:
x := reflect.ValueOf(node).Elem().FieldByName("Output")
// 它是<*bool Value>
// 我找不到一种方法来将一个新的*bool设置到底层(LogicNode)结构的Input或Output中...
}
}
我使用接口的原因是因为还有其他节点类型,如FloatNode和MathNode等,它们具有不同的字段,但它们实现了自己的run方法。
我成功地使用了Value的SetString或SetBool方法,但无法在那里设置指针... 提前感谢您的帮助。
英文:
I'm at a very early stage of understanding interfaces in Go. I'm writing some logical simulations and have something like the following code (I heavily simplify here):
Please see the comments for my question:
type LogicNode struct {
Input *bool
Output *bool
Operator string
Next Node
}
func (n *LogicNode) Run() {
// do some stuff here
n.Next.Run()
}
type Node interface {
Run()
}
func main() {
nodes := make([]Node, 1000)
for i := 0; i < 1000; i++ {
n := LogicNode{
//assign values etc.
}
nodes[i] = &n
}
for i, node := range nodes {
// I need to access LogicNode's Output pointer here, as a *bool.
// so I can set the same address to other Node's Input thereby "connecting" them.
// but I could only get something like this:
x := reflect.ValueOf(node).Elem().FieldByName("Output")
// which is <*bool Value>
// I couldn't find a way to set a new *bool to the underlying (LogicNode) Struct's Input or Output..
}
}
The reason I'm using interfaces is because there are other node types FloatNode MathNode etc. which have different fields, but they implement their own run method.
I've successfully used Value's SetString or SetBool methods, but can't set a pointer there... Thanks in advance.
答案1
得分: 10
你可以使用Set泛型版本来更新字段的值:
package main
import (
"fmt"
"reflect"
)
type LogicNode struct {
Input *bool
Output *bool
Operator string
Next Node
}
func (n *LogicNode) Run() {
// 在这里做一些操作
// n.Next.Run()
fmt.Printf("LogicNode.Input = %v (%v)\n", *n.Input, n.Input)
}
type Node interface {
Run()
}
func main() {
input := false
input2 := true
fmt.Printf("Input1 = %v (%v)\n", input, &input)
fmt.Printf("Input2 = %v (%v)\n", input2, &input2)
var node Node = &LogicNode{Input: &input} // 注意,接口是指针类型
node.Run()
x := reflect.ValueOf(node).Elem().FieldByName("Input")
x.Set(reflect.ValueOf(&input2))
node.Run()
}
输出结果:
Input1 = false (0x10500168)
Input2 = true (0x10500170)
LogicNode.Input = false (0x10500168)
LogicNode.Input = true (0x10500170)
Playground链接在这里。
英文:
You can use the Set generic version to update the field value:
package main
import (
"fmt"
"reflect"
)
type LogicNode struct {
Input *bool
Output *bool
Operator string
Next Node
}
func (n *LogicNode) Run() {
// do some stuff here
// n.Next.Run()
fmt.Printf("LogicNode.Input = %v (%v)\n", *n.Input, n.Input)
}
type Node interface {
Run()
}
func main() {
input := false
input2 := true
fmt.Printf("Input1 = %v (%v)\n", input, &input)
fmt.Printf("Input2 = %v (%v)\n", input2, &input2)
var node Node = &LogicNode{Input: &input} // Remember, interfaces are pointers
node.Run()
x := reflect.ValueOf(node).Elem().FieldByName("Input")
x.Set(reflect.ValueOf(&input2))
node.Run()
}
Outputs:
Input1 = false (0x10500168)
Input2 = true (0x10500170)
LogicNode.Input = false (0x10500168)
LogicNode.Input = true (0x10500170)
Playground here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论