简体   繁体   English

Golang - 通过接口获取指向结构字段的指针

[英]Golang - Get a pointer to a field of a struct through an interface

I'm at a very early stage of understanding interfaces in Go. 我正处于了解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. 我使用接口的原因是因为有其他节点类型FloatNode MathNode等具有不同的字段,但它们实现了自己的run方法。

I've successfully used Value's SetString or SetBool methods, but can't set a pointer there... Thanks in advance. 我已成功使用Value的SetString或SetBool方法,但无法在那里设置指针...提前感谢。

You can use the Set generic version to update the field value: 您可以使用Set generic version更新字段值:

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 . 这里的游乐场。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM