创建需要其他重复逻辑作为先决条件的函数(干净的代码)

我有以下我需要的 yaml 文件parse(解析按预期工作)并且需要data从 yaml 文件内容中提供一个应该由以下解耦函数公开的文件

我需要提供以下功能(这里是其中一些功能的示例,需要更多具有相同模式的功能......)

获取应用程序()

获取服务()

GetApp(应用名称)

GetServiceForApp(应用名称)

这是代码(有效...)

var DMZ = []byte(`

applications:

  - name: app1

    type: php

    src: /app1

    host: us

    use: 

      - redis

      - mysql


  - name: app2

    type: rust

    src: /app2

    host: eu

    use: 

      - mongo

      - mysql


  - name: app3

    type: golang

    src: /app3

    host: us

    use: 

      - postgress

      - mysql



services:

  - name: mongo

    type: db

    host: us


  - name: mysql

    type: db

    host: eu


  - name: postgress

    type: db

    host: us


  - name: redis

    type: db

    host: us   

`)


慕码人8056858
浏览 135回答 3
3回答

慕勒3428872

解析指针类型结构值中的值,该值将存储指针指向的结构中的值。然后 Create 方法接收所有你想从中获取结构内应用程序或服务值的方法。在所有方法中使用指针接收器,您将能够访问在解析 yaml 时更新的原始结构。创建一个指向该结构的空实例的指针并将其作为方法接收器传递。然后在解组中访问该结构以更新原始结构中的 yaml 数据。通过使用指向方法的指针接收器访问原始结构的值来访问每个函数中更新的结构。package mainimport (    "fmt"    "log"    yaml "gopkg.in/yaml.v2")var dmz = []byte(`applications:  - name: app1    type: php    src: /app1    host: us    use:       - redis      - mysql  - name: app2    type: rust    src: /app2    host: eu    use:       - mongo      - mysql  - name: app3    type: golang    src: /app3    host: us    use:       - postgress      - mysqlservices:  - name: mongo    type: db    host: us  - name: mysql    type: db    host: eu  - name: postgress    type: db    host: us  - name: redis    type: db    host: us   `)type DMZ struct {    Applications []*Applications `yaml:"applications,omitempty"`    Services     []*Services     `yaml:"services,omitempty"`}type Applications struct {    Name string    Type string    Src  string `yaml:"src,omitempty"`    use  []Use  `yaml:"use,omitempty"`}type Services struct {    Name string    Type string    Host string `yaml:"host,omitempty"`}type Use struct {    Name string `yaml:"name,omitempty"`    host string `yaml:"host,omitempty"`    Type string `yaml:"type,omitempty"`}func main() {    dm := &DMZ{}    result, err := dm.Parse(dmz)    dm.getApp("app1")    if err != nil {        fmt.Println(err)    }    fmt.Println(result)    fmt.Println(dm.getApp("app2"))    fmt.Println(dm.GetServiceForApp("mongo"))}func (dmz *DMZ) getApps() []*Applications {    return dmz.Applications}func (dmz *DMZ) getServices() []*Services {    return dmz.Services}func (dmz *DMZ) getApp(appname string) *Applications {    for _, value := range dmz.Applications {        if appname == value.Name {            fmt.Println((*value).Name)            return value        }    }    return nil}func (dmz *DMZ) GetServiceForApp(appname string) *Services {    for _, value := range dmz.Services {        if appname == value.Name {            return value        }    }    return nil}// Parse filefunc (dmz *DMZ) Parse(yamlContent []byte) (out *DMZ, err error) {    err = yaml.Unmarshal([]byte(yamlContent), &dmz)    if err != nil {        log.Fatal("Yaml file is not valid, Error: " + err.Error())    }    return dmz, err}游乐场上的工作代码如果你想让你的代码更干净,那么你也可以跳过从 parse 函数返回的结构。由于我们正在传递一个指针类型的接收器并将原始结构更新为:package mainimport (    "fmt"    "log"    yaml "gopkg.in/yaml.v2")var dmz = []byte(`applications:  - name: app1    type: php    src: /app1    host: us    use:       - redis      - mysql  - name: app2    type: rust    src: /app2    host: eu    use:       - mongo      - mysql  - name: app3    type: golang    src: /app3    host: us    use:       - postgress      - mysqlservices:  - name: mongo    type: db    host: us  - name: mysql    type: db    host: eu  - name: postgress    type: db    host: us  - name: redis    type: db    host: us   `)type DMZ struct {    Applications []*Applications `yaml:"applications,omitempty"`    Services     []*Services     `yaml:"services,omitempty"`}type Applications struct {    Name string    Type string    Src  string `yaml:"src,omitempty"`    use  []Use  `yaml:"use,omitempty"`}type Services struct {    Name string    Type string    Host string `yaml:"host,omitempty"`}type Use struct {    Name string `yaml:"name,omitempty"`    host string `yaml:"host,omitempty"`    Type string `yaml:"type,omitempty"`}func main() {    dm := &DMZ{}    dm.Parse(dmz)    fmt.Println(dm.getApp("app2"))    fmt.Println(dm.GetServiceForApp("mongo"))}func (dmz *DMZ) getApps() []*Applications {    return dmz.Applications}func (dmz *DMZ) getServices() []*Services {    return dmz.Services}func (dmz *DMZ) getApp(appname string) *Applications {    for _, value := range dmz.Applications {        if appname == value.Name {            fmt.Println((*value).Name)            return value        }    }    return nil}func (dmz *DMZ) GetServiceForApp(appname string) *Services {    for _, value := range dmz.Services {        if appname == value.Name {            return value        }    }    return nil}// Parse filefunc (dmz *DMZ) Parse(yamlContent []byte) {    if err := yaml.Unmarshal([]byte(yamlContent), &dmz); err != nil {        log.Fatal("Yaml file is not valid, Error: " + err.Error())    }}我们可以注意到 Parse 函数将变得更加干净,因为我们没有从它返回任何东西,我们只是使用方法 receiver 更新原始结构,这是实现您一直试图实现的目标的更好方法。您还可以选择通过将 struct 中的方法定义为您尝试为其实现接口的接收器来实现接口:package mainimport (    "fmt"    "log"    yaml "gopkg.in/yaml.v2")type DI interface {    GetApps() []*Applications    GetServices() *Services}var dmz = []byte(`applications:  - name: app1    type: php    src: /app1    host: us    use:       - redis      - mysql  - name: app2    type: rust    src: /app2    host: eu    use:       - mongo      - mysql  - name: app3    type: golang    src: /app3    host: us    use:       - postgress      - mysqlservices:  - name: mongo    type: db    host: us  - name: mysql    type: db    host: eu  - name: postgress    type: db    host: us  - name: redis    type: db    host: us   `)type DMZ struct {    Applications []*Applications `yaml:"applications,omitempty"`    Services     []*Services     `yaml:"services,omitempty"`}type Applications struct {    Name string    Type string    Src  string `yaml:"src,omitempty"`    use  []Use  `yaml:"use,omitempty"`}type Services struct {    Name string    Type string    Host string `yaml:"host,omitempty"`}type Use struct {    Name string `yaml:"name,omitempty"`    host string `yaml:"host,omitempty"`    Type string `yaml:"type,omitempty"`}func main() {    dm := &DMZ{}    dm.Parse(dmz)    fmt.Println(dm.getApp("app2"))    fmt.Println(dm.GetServiceForApp("mongo"))}func (dmz *DMZ) GetApps() []*Applications {    return dmz.Applications}func (dmz *DMZ) GetServices() []*Services {    return dmz.Services}func (dmz *DMZ) getApp(appname string) *Applications {    for _, value := range dmz.Applications {        if appname == value.Name {            fmt.Println((*value).Name)            return value        }    }    return nil}func (dmz *DMZ) GetServiceForApp(appname string) *Services {    for _, value := range dmz.Services {        if appname == value.Name {            return value        }    }    return nil}// Parse filefunc (dmz *DMZ) Parse(yamlContent []byte) {    if err := yaml.Unmarshal([]byte(yamlContent), &dmz); err != nil {        log.Fatal("Yaml file is not valid, Error: " + err.Error())    }}笔记:泛型很方便,但它们的代价是类型系统和运行时的复杂性。我们还没有找到一种设计,让价值与复杂性成正比,尽管我们继续考虑它。同时,Go 的内置映射和切片,加上使用空接口构造容器(显式拆箱)的能力,意味着在许多情况下,即使不那么流畅,也可以编写实现泛型能够实现的功能的代码。

阿波罗的战车

您可以定义一个接口并在结构中提供实现type DMZI interface {    GetApps() []Application    GetService() []Service    GetApp(name string) (Application, error)    GetServiceForApp(name string) ([]string, error)}type DMZ struct {    Application []Application `yaml:"applications,omitempty"`    Service     []Service     `yaml:"services,omitempty"`}func (dmz DMZ) GetApps() []Application {    return dmz.Application}func (dmz DMZ) GetService() []Service {    return dmz.Service}func (dmz DMZ) GetApp(name string) (Application, error) {    for _, app := range dmz.Application {        if app.Name == name {            return app, nil        }    }    return Application{}, fmt.Errorf("Did not find application with name %s", name)}func (dmz DMZ) GetServiceForApp(name string) ([]string, error) {    app, err := dmz.GetApp(name)    if err != nil {        return []string{}, err    }    return app.Use, nil}type Application struct {    Name string    Type string    Src  string   `yaml:"src,omitempty"`    Use  []string `yaml:"use,omitempty"`}type Service struct {    Name string    Type string    Host string `yaml:"host,omitempty"`}// Parse filefunc Parse(yamlContent []byte) (out DMZI, err error) {    dmz := DMZ{}    err = yaml.Unmarshal([]byte(yamlContent), &dmz)    if err != nil {        fmt.Println("Yaml file is not valid, Error: " + err.Error())    }    return dmz, err}因此,您可以调用返回接口上的方法,例如fmt.Printf("Apps : %+v\n", dmz.GetApps())fmt.Printf("Service : %+v\n", dmz.GetService())更新评论中要求的主要方法func main() {    dmz, err := Parse([]byte(ymlStr))    if err != nil {        panic(err)    }    fmt.Printf("Apps : %+v\n", dmz.GetApps())    fmt.Printf("Service : %+v\n", dmz.GetService())}将打印Apps : [{Name:app1 Type:php Src:/app1 Use:[redis mysql]} {Name:app2 Type:rust Src:/app2 Use:[mongo mysql]} {Name:app3 Type:golang Src:/app3 Use:[postgress mysql]}]Service : [{Name:mongo Type:db Host:us} {Name:mysql Type:db Host:eu} {Name:postgress Type:db Host:us} {Name:redis Type:db Host:us}]

慕森卡

我已经稍微更改了您的代码并完成了我认为您所要求的,即每当您创建 DMZ 的新实例时始终调用“Parse”。这就是您使用Dargo执行此操作的方式。查看底部以了解代码如何将 DMZ 绑定到 ServiceLocator 以及如何获取 DMZ 的新实例type DMZ struct {    Applications []*Applications `yaml:"applications,omitempty"`    Services     []*Services     `yaml:"services,omitempty"`}// This method is called every time DMZ is created via the Dargo APIfunc (dmz *DMZ) DargoInitialize(ioc.Descriptor) error {    // get ur bytes from... wherever    Parse(dmz, []byte{})}type Applications struct {    Name string    Type string    Src  string `yaml:"src,omitempty"`    use  []Use  `yaml:"use,omitempty"`}type Services struct {    Name string    Type string    Host string `yaml:"host,omitempty"`}type Use struct {    Name string `yaml:"name,omitempty"`    host string `yaml:"host,omitempty"`    Type string `yaml:"type,omitempty"`}// Parse filefunc Parse(dmz *DMZ, yamlContent []byte) (out *DMZ, err error) {    err = yaml.Unmarshal([]byte(yamlContent), &dmz)    if err != nil {        logs.Error("Yaml file is not valid, Error: " + err.Error())    }    return dmz, err}func useDargo() error {    locator, err := ioc.CreateAndBind("example", func(binder ioc.Binder) error {        binder.Bind("DMZ", &DMZ{}).InScope(ioc.PerLookup)    })    if err != nil {        return err    }    // This is how you would get your instances of DMZ    locator.GetDService("DMZ")}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go