// getCommands func getCommands() []cli.Command { command := cli.Command{ Name: "web", Usage: "run web server", Action: runWeb, Flags: []cli.Flag{ cli.StringFlag{ Name: "host", Value: "0.0.0.0", Usage: "bind host", }, cli.IntFlag{ Name: "port,p", Value: DefaultPort, Usage: "bind port", }, cli.StringFlag{ Name: "env,e", Value: "prod", Usage: "runtime environment, dev|test|prod", }, }, } return []cli.Command{command} }
上面那些代碼很是不容易理解,咱們須要把它拆分來看
當咱們直接實例化一個類的時候,若是大括號豎着排,那麼裏面的成員賦值後要加個逗號web
b := Taoshihan{ Name: "taoshihan", } fmt.Println(b.Name)
定義一個接口,接口裏面有一個成員方法app
type Flag interface { GetName() string }
定義另外一個類型,這個類型恰好就有這個方法,那麼就能夠認爲這個類型實現了接口spa
type StringFlag struct { } func (t StringFlag) GetName() string { return "taoshihan" }
這個時候若是定義Flag類型的變量,那麼StringFlag也能被賦值過去code
var a Flag a = StringFlag{} a.GetName()
再回到原代碼中的邏輯,若是使用下面這種方式就很是容易理解了server
var myflag []Flag myflag = append(myflag, StringFlag{}, StringFlag{}) command := Command{ Flags: myflag, }
完整源碼:blog
package main import "fmt" type Flag interface { GetName() string } type Command struct { Flags []Flag } type StringFlag struct { } func (t StringFlag) GetName() string { return "taoshihan" } type Taoshihan struct { Name string } func main() { // var a Flag // a = StringFlag{} // a.GetName() // b := Taoshihan{ // Name: "taoshihan", // } // fmt.Println(b.Name) var myflag []Flag myflag = append(myflag, StringFlag{}, StringFlag{}) command := Command{ Flags: myflag, } for _, p := range command.Flags { fmt.Println(p.GetName()) } }