访问嵌套结构体中的字段

huangapple go评论79阅读模式
英文:

Access field in nested structs

问题

我遇到了一个本应简单的问题。我正在处理一个使用codegangsta的优秀cli包的项目,但是我试图访问嵌套结构中的属性时失败了。

举个例子,我有以下代码:

func Something() []cli.Flag {
    return []cli.Flag{
        cli.StringFlag{
            Name: "awesome",
            Usage: "be awesome",
        },
        cli.StringFlag{
            Name: "awesome2",
        },
        // <etc.>
    }
}

我有一个函数接收返回的flags []cli.Flag,并尝试打印出每个成员的Name字符串值,但是我似乎无法访问切片中的嵌套内容。请问正确的做法是什么?

编辑:这是我做的事情,包括Mayank的优秀答案中的补充部分:

func PrintFlagsForDriver(name string) error {
    for driverName := range drivers {
        if name == driverName {
            driver := drivers[driverName]
            flags := driver.GetCreateFlags()
            stringFlag, ok := flags[0].(cli.StringFlag)
            if ok {
                fmt.Println(stringFlag.Name)
            }
        }
    }
    return fmt.Errorf("Driver %s not found", name)
}

现在我得到了一个index out of range的运行时错误,但我认为那是我做错了其他事情。

英文:

I'm having trouble with something that should be simple. I'm working on something that uses codegangsta's excellent cli package, but I'm trying to access a property from a nested struct and failing.

As an example, I have:

func Something() []cli.Flag {
    return []cli.Flag{
        cli.StringFlag{
            Name: awesome
            Usage: &quot;be awesome&quot;
           },
         cli.StringFlag{
            Name: awesome2
           },
           &lt;etc.&gt;
         }

I have a function that takes in the returned flags []cli.Flag and tries to print out the string value of Name for each member, but I can't seem to access the nested content in the slice. What is the proper way of doing this?

EDIT: Here's what I did, with additions from Mayank's excellent answer

func PrintFlagsForDriver(name string) error {

        for driverName := range drivers {
                if name == driverName {
                        driver := drivers[driverName]
                        flags := driver.GetCreateFlags()
                        stringFlag, ok := flags[0].(cli.StringFlag)
                        if ok {
                                fmt.Println(stringFlag.Name)
                        }
                }
        }
        return fmt.Errorf(&quot;Driver %s not found&quot;, name)
}

I'm getting an index out of range runtime error now, but I think that's something else I'm doing wrong.

答案1

得分: 3

我假设你是这样访问值的:

package main

import "fmt"
import "github.com/codegangsta/cli"

func main() {

    fmt.Println("Hello, playground")
    a := Something()
    fmt.Printf("%T \n", a[0].Name)
}

func Something() []cli.Flag {
    return []cli.Flag{
        cli.StringFlag{
            Name:  "awesome",
            Usage: "be awesome",
        },
        cli.StringFlag{
            Name: "awesome2",
        },
    }
}

这将会给你以下错误:

./main.go:10: a[0].Name undefined (type cli.Flag has no field or method Name)

问题出在你通过接口cli.Flag访问结构体cli.StringFlag的值。你需要将这个接口转换为实际的结构体类型。

希望下面的代码能够解决问题。

package main

import "fmt"
import "github.com/codegangsta/cli"

func main() {

    a := Something()
    stringFlag, ok := a[0].(cli.StringFlag)
    if ok {
        fmt.Println(stringFlag.Name)
    }

}

func Something() []cli.Flag {
    return []cli.Flag{
        cli.StringFlag{
            Name:  "awesome",
            Usage: "be awesome",
        },
        cli.StringFlag{
            Name: "awesome2",
        },
    }
}
英文:

I assume you are accessing the value something like this

package main

import &quot;fmt&quot;
import &quot;github.com/codegangsta/cli&quot;

func main() {

	fmt.Println(&quot;Hello, playground&quot;)
	a := Something()
	fmt.Printf(&quot;%T \n&quot;, a[0].Name)
}

func Something() []cli.Flag {
	return []cli.Flag{
		cli.StringFlag{
			Name:  &quot;awesome&quot;,
			Usage: &quot;be awesome&quot;,
		},
		cli.StringFlag{
			Name: &quot;awesome2&quot;,
		},
	}
}

Which will give you following error

./main.go:10: a[0].Name undefined (type cli.Flag has no field or method Name)

And the problem with this code is that you are accessing the struct cli.StringFlag values through an interface cli.Flag. You need to type convert this interface to actual struct type.

Hopefully following code will make things clear.

package main

import &quot;fmt&quot;
import &quot;github.com/codegangsta/cli&quot;

func main() {

	a := Something()
	stringFlag, ok := a[0].(cli.StringFlag)
	if ok {
		fmt.Println(stringFlag.Name)
	}

}

func Something() []cli.Flag {
	return []cli.Flag{
		cli.StringFlag{
			Name:  &quot;awesome&quot;,
			Usage: &quot;be awesome&quot;,
		},
		cli.StringFlag{
			Name: &quot;awesome2&quot;,
		},
	}
}

答案2

得分: 0

由于您没有粘贴代码中的Name属性的读取部分,我只能猜测,您可能需要进行接口检查:

if stringFlag, ok := flags[0].(cli.StringFlag); ok {
    fmt.Println(stringFlag.Name)
}

请注意,这只是一个猜测,具体取决于您的代码实现。

英文:

as you not paste the code reading the Name property, I just guess, you need a interface check

if stringFlag, ok := flags[0].(cli.StringFlag); ok{
    fmt.Println(stringFlag.Name)
}

huangapple
  • 本文由 发表于 2015年7月22日 08:15:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/31551788.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定