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)
}
}
Это должно работать должным образом.
Основная проблема заключалась в обратном типе метода зависимости