Golang - значение ключа для ввода текста/шаблона

Мне нужно вернуть форму ключевого значения текстового шаблона, которое будет похоже на комментарий и команду, как показано ниже.

 #Description for npm install 
   npm install
 #Description for test
   npm test
 #Description for test2 
   run test2

Для этого я создал такую функцию, как:

// example with switch
func (d Dependency) TypeCommand() Command {
    switch d.Type {
    case "runner":

        cmd1 := Command{"#Description for npm install", "npm install"}
        cmd2 := Command{"#Description for test", "npm test"}
        cmd3 := Command{"#Description for test2", "run test2"}

    case "runner2":
        return "test 2"

    }
    return "command_baz"
}

Шаблон:

const tmpl = '
{{- range .File.Dependency}}

{{.TypeCommand}}
{{end}}'

type Command struct {
    Info    string
    Command string
}

Когда я меняю шаблон на следующее, я получаю сообщение об ошибке:

const tmpl = '
    {{- range .File.Dependency}}

     {{  TypeCommand .}}
   {{ range .Command}}
    {{ .Info }}
    {{ .Command }}
   {{end}}
  {{end}}
        '

executing "tmpl3.txt" at <.Command>: can't evaluate field Command in type *Dependency

Я использую это как ссылку.

Ответ 1

Сообщение об ошибке, которое вы получаете, состоит в том, что вы просто отбрасываете возвращаемое значение TypeCommand вместо того, чтобы передавать его туда, где вы пытаетесь получить доступ к своим полям структуры. Мы могли бы исправить это, но это, вероятно, не то, что вы хотели сделать в любом случае, так как ваша функция TypeCommand выглядит так, как будто она должна возвращать несколько команд вместо одного. Так что сначала перепишите запись:

func (d Dependency) TypeCommand() []Command {
    switch d.Type {
    case "runner":

        return []Command{
          Command{"#Description for npm install", "npm install"},
          Command{"#Description for test", "npm test"},
          Command{"#Description for test2", "run test2"},
        }

    case "runner2":
        return []Command{Command{"#test 2", "foo"}}

    }
    return []Command{Command{"#command_baz", "baz"}}
}

Теперь, когда мы возвращаем несколько команд, мы можем просто перемещаться по ним в шаблоне, и они будут автоматически связаны. Я немного подделал ваш шаблон к следующему:

const tmpl = '
{{- range .File.Dependency}}
  {{- range .TypeCommand }}
{{ .Info}}
  {{ .Command}}
{{- end}}{{end}}'

Когда я запускал это на игровой площадке Go, это дало мне следующий результат, который, казалось, был тем, за что вы шли:

#Description for npm install
  npm install
#Description for test
  npm test
#Description for test2
  run test2
#test 2
  foo

Ответ 2

    package main

import (
    "os"
    "text/template"
)

type File struct {
    TypeVersion string 'yaml:"_type-version"'
    Dependency  []Dependency
}

type Dependency struct {
    Name string
    Type string
    CWD  string
}

type Command struct {
    Info    string
    Command string
}

func  (d Dependency) TypeCommand() []Command {
    switch d.Type {
    case "runner":

        return []Command{
          {"#Description for npm install", "npm install"},
          {"#Description for test", "npm test"},
          {"#Description for test2", "run test2"},
        }

    case "runner2":
        return []Command{{"#test 2", "foo"}}

    }
    return []Command{{"#command_baz", "baz"}}
}

type Install map[string]string

const tmpl = '
{{- range .File.Dependency}}
  {{- range .TypeCommand }}
{{ .Info}}
  {{ .Command}}
{{- end}}{{end}}'

type API map[string]string

func main() {
    f := new(File)
    f.Dependency = []Dependency{{
        Name: "ui",
        Type: "runner",
        CWD:  "/ui",
    }, {
        Name: "ui2",
        Type: "runner2",
        CWD:  "/ui2",
    }}

    t, err := template.New("t").Parse(tmpl)
    if err != nil {
        panic(err)
    }

    var data struct {
        File *File
        API  API
    }
    data.File = f

    if err := t.Execute(os.Stdout, data); err != nil {
        panic(err)
    }
}

Это должно работать должным образом.

Основная проблема заключалась в обратном типе метода зависимости