匿名结构作为模板中的管道
Anonymous struct as pipeline in template
有没有办法在 html/template
中执行以下操作?
{{template "mytemplate" struct{Foo1, Foo2 string}{"Bar1", "Bar2"}}}
实际上在模板中,如上。不是通过 FuncMap
中注册的函数,其中 returns 结构。
我试过了,但是 Parse
恐慌,see Playground。也许只是语法错误?
正如其他人所说,这是不可能的。模板在运行时解析,无需 Go 编译器的帮助。因此允许任意 Go 语法是不可行的(尽管请注意,这并非不可能,因为标准库包含解析 Go 源文本的所有工具,请参阅标准中的包 "prefixed" 和 go/
库)。按照设计理念,复杂的逻辑应该在模板之外。
回到你的例子:
struct{Foo1, Foo2 string}{"Bar1", "Bar2"}
这是一个结构composite literal,模板不支持它,无论是在调用另一个模板还是在其他地方。
使用自定义 "argument" 调用另一个模板具有以下语法(引用自 text/template
: Actions):
{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.
TL;DR; 管道可以是一个常量,一个表达式,表示某个字段或某个值的方法(方法将被调用的地方及其 return value 将被使用),它可能是对某些 "template-builtin" 函数或自定义注册函数的调用,或者映射中的值。
其中 Pipeline 是:
A pipeline is a possibly chained sequence of "commands". A command is a simple value (argument) or a function or method call, possibly with multiple arguments:
Argument
The result is the value of evaluating the argument.
.Method [Argument...]
The method can be alone or the last element of a chain but,
unlike methods in the middle of a chain, it can take arguments.
The result is the value of calling the method with the
arguments:
dot.Method(Argument1, etc.)
functionName [Argument...]
The result is the value of calling the function associated
with the name:
function(Argument1, etc.)
Functions and function names are described below.
而 Argument 是:
An argument is a simple value, denoted by one of the following.
- A boolean, string, character, integer, floating-point, imaginary
or complex constant in Go syntax. These behave like Go's untyped
constants. Note that, as in Go, whether a large integer constant
overflows when assigned or passed to a function can depend on whether
the host machine's ints are 32 or 64 bits.
- The keyword nil, representing an untyped Go nil.
- The character '.' (period):
.
The result is the value of dot.
- A variable name, which is a (possibly empty) alphanumeric string
preceded by a dollar sign, such as
$piOver2
or
$
The result is the value of the variable.
Variables are described below.
- The name of a field of the data, which must be a struct, preceded
by a period, such as
.Field
The result is the value of the field. Field invocations may be
chained:
.Field1.Field2
Fields can also be evaluated on variables, including chaining:
$x.Field1.Field2
- The name of a key of the data, which must be a map, preceded
by a period, such as
.Key
The result is the map element value indexed by the key.
Key invocations may be chained and combined with fields to any
depth:
.Field1.Key1.Field2.Key2
Although the key must be an alphanumeric identifier, unlike with
field names they do not need to start with an upper case letter.
Keys can also be evaluated on variables, including chaining:
$x.key1.key2
- The name of a niladic method of the data, preceded by a period,
such as
.Method
The result is the value of invoking the method with dot as the
receiver, dot.Method(). Such a method must have one return value (of
any type) or two return values, the second of which is an error.
If it has two and the returned error is non-nil, execution terminates
and an error is returned to the caller as the value of Execute.
Method invocations may be chained and combined with fields and keys
to any depth:
.Field1.Key1.Method1.Field2.Key2.Method2
Methods can also be evaluated on variables, including chaining:
$x.Method1.Field
- The name of a niladic function, such as
fun
The result is the value of invoking the function, fun(). The return
types and values behave as in methods. Functions and function
names are described below.
- A parenthesized instance of one the above, for grouping. The result
may be accessed by a field or map key invocation.
print (.F1 arg1) (.F2 arg2)
(.StructValuedMethod "arg").Field
正确的解决方案是注册一个自定义函数,该函数构造要传递给模板调用的值,如您在相关/可能的重复项中所见:
另一种半解决方案是使用内置的 print
或 printf
函数来连接您要传递的值,但这需要在另一个模板中拆分。
如@icza 所述,这是不可能的。
但是,您可能希望为模板提供通用 dict
函数,以允许从参数列表构建 map[string]interface{}
。这在另一个答案中有解释:
有没有办法在 html/template
中执行以下操作?
{{template "mytemplate" struct{Foo1, Foo2 string}{"Bar1", "Bar2"}}}
实际上在模板中,如上。不是通过 FuncMap
中注册的函数,其中 returns 结构。
我试过了,但是 Parse
恐慌,see Playground。也许只是语法错误?
正如其他人所说,这是不可能的。模板在运行时解析,无需 Go 编译器的帮助。因此允许任意 Go 语法是不可行的(尽管请注意,这并非不可能,因为标准库包含解析 Go 源文本的所有工具,请参阅标准中的包 "prefixed" 和 go/
库)。按照设计理念,复杂的逻辑应该在模板之外。
回到你的例子:
struct{Foo1, Foo2 string}{"Bar1", "Bar2"}
这是一个结构composite literal,模板不支持它,无论是在调用另一个模板还是在其他地方。
使用自定义 "argument" 调用另一个模板具有以下语法(引用自 text/template
: Actions):
{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.
TL;DR; 管道可以是一个常量,一个表达式,表示某个字段或某个值的方法(方法将被调用的地方及其 return value 将被使用),它可能是对某些 "template-builtin" 函数或自定义注册函数的调用,或者映射中的值。
其中 Pipeline 是:
A pipeline is a possibly chained sequence of "commands". A command is a simple value (argument) or a function or method call, possibly with multiple arguments:
Argument The result is the value of evaluating the argument. .Method [Argument...] The method can be alone or the last element of a chain but, unlike methods in the middle of a chain, it can take arguments. The result is the value of calling the method with the arguments: dot.Method(Argument1, etc.) functionName [Argument...] The result is the value of calling the function associated with the name: function(Argument1, etc.) Functions and function names are described below.
而 Argument 是:
An argument is a simple value, denoted by one of the following.
- A boolean, string, character, integer, floating-point, imaginary or complex constant in Go syntax. These behave like Go's untyped constants. Note that, as in Go, whether a large integer constant overflows when assigned or passed to a function can depend on whether the host machine's ints are 32 or 64 bits. - The keyword nil, representing an untyped Go nil. - The character '.' (period): . The result is the value of dot. - A variable name, which is a (possibly empty) alphanumeric string preceded by a dollar sign, such as $piOver2 or $ The result is the value of the variable. Variables are described below. - The name of a field of the data, which must be a struct, preceded by a period, such as .Field The result is the value of the field. Field invocations may be chained: .Field1.Field2 Fields can also be evaluated on variables, including chaining: $x.Field1.Field2 - The name of a key of the data, which must be a map, preceded by a period, such as .Key The result is the map element value indexed by the key. Key invocations may be chained and combined with fields to any depth: .Field1.Key1.Field2.Key2 Although the key must be an alphanumeric identifier, unlike with field names they do not need to start with an upper case letter. Keys can also be evaluated on variables, including chaining: $x.key1.key2 - The name of a niladic method of the data, preceded by a period, such as .Method The result is the value of invoking the method with dot as the receiver, dot.Method(). Such a method must have one return value (of any type) or two return values, the second of which is an error. If it has two and the returned error is non-nil, execution terminates and an error is returned to the caller as the value of Execute. Method invocations may be chained and combined with fields and keys to any depth: .Field1.Key1.Method1.Field2.Key2.Method2 Methods can also be evaluated on variables, including chaining: $x.Method1.Field - The name of a niladic function, such as fun The result is the value of invoking the function, fun(). The return types and values behave as in methods. Functions and function names are described below. - A parenthesized instance of one the above, for grouping. The result may be accessed by a field or map key invocation. print (.F1 arg1) (.F2 arg2) (.StructValuedMethod "arg").Field
正确的解决方案是注册一个自定义函数,该函数构造要传递给模板调用的值,如您在相关/可能的重复项中所见:
另一种半解决方案是使用内置的 print
或 printf
函数来连接您要传递的值,但这需要在另一个模板中拆分。
如@icza 所述,这是不可能的。
但是,您可能希望为模板提供通用 dict
函数,以允许从参数列表构建 map[string]interface{}
。这在另一个答案中有解释: