El formulario de paquete decodifica URL. Valores en Valores GO y codifica el valor (s) de GO en URL. Valores.
Tiene las siguientes características:
"Array[0]"
y solo "Array"
con múltiples valores aprobados.array
o map
, la array
y map
se dejan como valores predeterminados en la estructura.Preguntas comunes
array/slice
con array[idx]/slice[idx]
, ¿en qué orden se analizan? array/slice
luego array[idx]/slice[idx]
string
bool
int
, int8
, int16
, int32
, int64
uint
, uint8
, uint16
, uint32
, uint64
float32
, float64
struct
y anonymous struct
interface{}
time.Time
- De forma predeterminada usando RFC3339pointer
a uno de los tipos anterioresslice
array
map
custom types
pueden anular cualquiera de los tipos anteriores Nota : map
, struct
y la anidación slice
son ad infinitum.
Use Go Get.
go get github.com/go-playground/form
Luego importe el paquete de formulario en su propio código.
import "github.com/go-playground/form/v4"
.
para separar campos/estructuras. (por ejemplo, structfield.field
)[index or key]
para el acceso al índice de una porción/matriz o clave para el mapa. (por ejemplo, arrayfield[0]
, mapfield[keyvalue]
) < form method =" POST " >
< input type =" text " name =" Name " value =" joeybloggs "/>
< input type =" text " name =" Age " value =" 3 "/>
< input type =" text " name =" Gender " value =" Male "/>
< input type =" text " name =" Address[0].Name " value =" 26 Here Blvd. "/>
< input type =" text " name =" Address[0].Phone " value =" 9(999)999-9999 "/>
< input type =" text " name =" Address[1].Name " value =" 26 There Blvd. "/>
< input type =" text " name =" Address[1].Phone " value =" 1(111)111-1111 "/>
< input type =" text " name =" active " value =" true "/>
< input type =" text " name =" MapExample[key] " value =" value "/>
< input type =" text " name =" NestedMap[key][key] " value =" value "/>
< input type =" text " name =" NestedArray[0][0] " value =" value "/>
< input type =" submit "/>
</ form >
Descodificación
package main
import (
"fmt"
"log"
"net/url"
"github.com/go-playground/form/v4"
)
// Address contains address information
type Address struct {
Name string
Phone string
}
// User contains user information
type User struct {
Name string
Age uint8
Gender string
Address [] Address
Active bool `form:"active"`
MapExample map [ string ] string
NestedMap map [ string ] map [ string ] string
NestedArray [][] string
}
// use a single instance of Decoder, it caches struct info
var decoder * form. Decoder
func main () {
decoder = form . NewDecoder ()
// this simulates the results of http.Request's ParseForm() function
values := parseForm ()
var user User
// must pass a pointer
err := decoder . Decode ( & user , values )
if err != nil {
log . Panic ( err )
}
fmt . Printf ( "%#v n " , user )
}
// this simulates the results of http.Request's ParseForm() function
func parseForm () url. Values {
return url. Values {
"Name" : [] string { "joeybloggs" },
"Age" : [] string { "3" },
"Gender" : [] string { "Male" },
"Address[0].Name" : [] string { "26 Here Blvd." },
"Address[0].Phone" : [] string { "9(999)999-9999" },
"Address[1].Name" : [] string { "26 There Blvd." },
"Address[1].Phone" : [] string { "1(111)111-1111" },
"active" : [] string { "true" },
"MapExample[key]" : [] string { "value" },
"NestedMap[key][key]" : [] string { "value" },
"NestedArray[0][0]" : [] string { "value" },
}
}
Codificación
package main
import (
"fmt"
"log"
"github.com/go-playground/form/v4"
)
// Address contains address information
type Address struct {
Name string
Phone string
}
// User contains user information
type User struct {
Name string
Age uint8
Gender string
Address [] Address
Active bool `form:"active"`
MapExample map [ string ] string
NestedMap map [ string ] map [ string ] string
NestedArray [][] string
}
// use a single instance of Encoder, it caches struct info
var encoder * form. Encoder
func main () {
encoder = form . NewEncoder ()
user := User {
Name : "joeybloggs" ,
Age : 3 ,
Gender : "Male" ,
Address : [] Address {
{ Name : "26 Here Blvd." , Phone : "9(999)999-9999" },
{ Name : "26 There Blvd." , Phone : "1(111)111-1111" },
},
Active : true ,
MapExample : map [ string ] string { "key" : "value" },
NestedMap : map [ string ] map [ string ] string { "key" : { "key" : "value" }},
NestedArray : [][] string {{ "value" }},
}
// must pass a pointer
values , err := encoder . Encode ( & user )
if err != nil {
log . Panic ( err )
}
fmt . Printf ( "%#v n " , values )
}
Descifrador
decoder . RegisterCustomTypeFunc ( func ( vals [] string ) ( interface {}, error ) {
return time . Parse ( "2006-01-02" , vals [ 0 ])
}, time. Time {})
ADICIONAL: Si se registra un tipo de estructura, la función solo se llamará si existe un valor URL para la estructura y no solo para los campos de estructura, por ejemplo. URL.Values {"Usuario": "Nombre%3DjoEyBloggs"} llamará a la función de tipo personalizado con 'Usuario' como el tipo, sin embargo, URL.Values {"User.name": "JoeyBloggs"} no lo hará.
Codificador
encoder . RegisterCustomTypeFunc ( func ( x interface {}) ([] string , error ) {
return [] string { x .(time. Time ). Format ( "2006-01-02" )}, nil
}, time. Time {})
Puede decirle a la formulario que ignore los campos que usan -
en la etiqueta
type MyStruct struct {
Field string `form:"-"`
}
Puede decirle a la formulario que omita los campos vacíos usando ,omitempty
o FieldName,omitempty
en la etiqueta
type MyStruct struct {
Field string `form:",omitempty"`
Field2 string `form:"CustomFieldName,omitempty"`
}
Para maximizar la compatibilidad con otros sistemas, el codificador intenta evitar usar índices de matriz en URL. Valores si es posible.
p.ej.
// A struct field of
Field [] string { "1" , "2" , "3" }
// will be output a url.Value as
"Field" : [] string { "1" , "2" , "3" }
and not
"Field[0]" : [] string { "1" }
"Field[1]" : [] string { "2" }
"Field[2]" : [] string { "3" }
// however there are times where it is unavoidable, like with pointers
i := int ( 1 )
Field [] * string { nil , nil , & i }
// to avoid index 1 and 2 must use index
"Field[2]" : [] string { "1" }
Nota: La asignación 1 y B/OP en los primeros 4 decodes es en realidad la estructura que se asigna al pasarlo, por lo que las primitivas son en realidad cero asignación.
go test - run = NONE - bench = . - benchmem = true . / ...
goos : darwin
goarch: arm64
pkg: github . com / go - playground / form / v4 / benchmarks
BenchmarkSimpleUserDecodeStruct - 8 8704111 121.1 ns / op 64 B / op 1 allocs / op
BenchmarkSimpleUserDecodeStructParallel - 8 35916134 32.89 ns / op 64 B / op 1 allocs / op
BenchmarkSimpleUserEncodeStruct - 8 3746173 320.7 ns / op 485 B / op 10 allocs / op
BenchmarkSimpleUserEncodeStructParallel - 8 7293147 180.0 ns / op 485 B / op 10 allocs / op
BenchmarkPrimitivesDecodeStructAllPrimitivesTypes - 8 2993259 400.5 ns / op 96 B / op 1 allocs / op
BenchmarkPrimitivesDecodeStructAllPrimitivesTypesParallel - 8 13023300 97.70 ns / op 96 B / op 1 allocs / op
BenchmarkPrimitivesEncodeStructAllPrimitivesTypes - 8 643202 1767 ns / op 2977 B / op 35 allocs / op
BenchmarkPrimitivesEncodeStructAllPrimitivesTypesParallel - 8 1000000 1202 ns / op 2978 B / op 35 allocs / op
BenchmarkComplexArrayDecodeStructAllTypes - 8 172630 6822 ns / op 2008 B / op 121 allocs / op
BenchmarkComplexArrayDecodeStructAllTypesParallel - 8 719788 1735 ns / op 2009 B / op 121 allocs / op
BenchmarkComplexArrayEncodeStructAllTypes - 8 197052 5839 ns / op 7087 B / op 104 allocs / op
BenchmarkComplexArrayEncodeStructAllTypesParallel - 8 348039 3247 ns / op 7089 B / op 104 allocs / op
BenchmarkComplexMapDecodeStructAllTypes - 8 139246 8550 ns / op 5313 B / op 130 allocs / op
BenchmarkComplexMapDecodeStructAllTypesParallel - 8 409018 3143 ns / op 5317 B / op 130 allocs / op
BenchmarkComplexMapEncodeStructAllTypes - 8 208833 5515 ns / op 4257 B / op 103 allocs / op
BenchmarkComplexMapEncodeStructAllTypesParallel - 8 523833 2182 ns / op 4258 B / op 103 allocs / op
BenchmarkDecodeNestedStruct - 8 807690 1408 ns / op 344 B / op 14 allocs / op
BenchmarkDecodeNestedStructParallel - 8 3409441 359.6 ns / op 344 B / op 14 allocs / op
BenchmarkEncodeNestedStruct - 8 1488520 803.6 ns / op 653 B / op 16 allocs / op
BenchmarkEncodeNestedStructParallel - 8 3570204 346.6 ns / op 653 B / op 16 allocs / op
Los puntos de referencia de la competencia se pueden encontrar aquí
Aquí hay una lista de software que complementa el uso de esta decodificación de publicación de la biblioteca.
Distribuido bajo la licencia MIT, consulte el archivo de licencia en el código para obtener más detalles.