3 回答

TA貢獻(xiàn)1848條經(jīng)驗(yàn) 獲得超6個(gè)贊
解析指針類(lèi)型結(jié)構(gòu)值中的值,該值將存儲(chǔ)指針指向的結(jié)構(gòu)中的值。然后 Create 方法接收所有你想從中獲取結(jié)構(gòu)內(nèi)應(yīng)用程序或服務(wù)值的方法。
在所有方法中使用指針接收器,您將能夠訪問(wèn)在解析 yaml 時(shí)更新的原始結(jié)構(gòu)。
創(chuàng)建一個(gè)指向該結(jié)構(gòu)的空實(shí)例的指針并將其作為方法接收器傳遞。然后在解組中訪問(wèn)該結(jié)構(gòu)以更新原始結(jié)構(gòu)中的 yaml 數(shù)據(jù)。通過(guò)使用指向方法的指針接收器訪問(wèn)原始結(jié)構(gòu)的值來(lái)訪問(wèn)每個(gè)函數(shù)中更新的結(jié)構(gòu)。
package main
import (
"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
- 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
`)
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 file
func (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
}
游樂(lè)場(chǎng)上的工作代碼
如果你想讓你的代碼更干凈,那么你也可以跳過(guò)從 parse 函數(shù)返回的結(jié)構(gòu)。由于我們正在傳遞一個(gè)指針類(lèi)型的接收器并將原始結(jié)構(gòu)更新為:
package main
import (
"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
- 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
`)
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 file
func (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 函數(shù)將變得更加干凈,因?yàn)槲覀儧](méi)有從它返回任何東西,我們只是使用方法 receiver 更新原始結(jié)構(gòu),這是實(shí)現(xiàn)您一直試圖實(shí)現(xiàn)的目標(biāo)的更好方法。
您還可以選擇通過(guò)將 struct 中的方法定義為您嘗試為其實(shí)現(xiàn)接口的接收器來(lái)實(shí)現(xiàn)接口:
package main
import (
"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
- 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
`)
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 file
func (dmz *DMZ) Parse(yamlContent []byte) {
if err := yaml.Unmarshal([]byte(yamlContent), &dmz); err != nil {
log.Fatal("Yaml file is not valid, Error: " + err.Error())
}
}
筆記:
泛型很方便,但它們的代價(jià)是類(lèi)型系統(tǒng)和運(yùn)行時(shí)的復(fù)雜性。我們還沒(méi)有找到一種設(shè)計(jì),讓價(jià)值與復(fù)雜性成正比,盡管我們繼續(xù)考慮它。同時(shí),Go 的內(nèi)置映射和切片,加上使用空接口構(gòu)造容器(顯式拆箱)的能力,意味著在許多情況下,即使不那么流暢,也可以編寫(xiě)實(shí)現(xiàn)泛型能夠?qū)崿F(xiàn)的功能的代碼。

TA貢獻(xiàn)1862條經(jīng)驗(yàn) 獲得超6個(gè)贊
您可以定義一個(gè)接口并在結(jié)構(gòu)中提供實(shí)現(xiàn)
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 file
func 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
}
因此,您可以調(diào)用返回接口上的方法,例如
fmt.Printf("Apps : %+v\n", dmz.GetApps())
fmt.Printf("Service : %+v\n", dmz.GetService())
更新
評(píng)論中要求的主要方法
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}]

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超8個(gè)贊
我已經(jīng)稍微更改了您的代碼并完成了我認(rèn)為您所要求的,即每當(dāng)您創(chuàng)建 DMZ 的新實(shí)例時(shí)始終調(diào)用“Parse”。這就是您使用Dargo執(zhí)行此操作的方式。查看底部以了解代碼如何將 DMZ 綁定到 ServiceLocator 以及如何獲取 DMZ 的新實(shí)例
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 API
func (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 file
func 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")
}
- 3 回答
- 0 關(guān)注
- 192 瀏覽
添加回答
舉報(bào)