Форма пакета декодирует url.vallies в значение (ы) GO и кодирует значение (ы) go в url.values.
Он имеет следующие функции:
"Array[0]"
и просто "Array"
с несколькими значениями.array
или значения map
не переданы, array
и map
остаются в качестве значений по умолчанию в структуре.Общие вопросы
array/slice
с array[idx]/slice[idx]
, в каком порядке они анализируются? array/slice
, затем array[idx]/slice[idx]
string
bool
int
, int8
, int16
, int32
, int64
uint
, uint8
, uint16
, uint32
, uint64
float32
, float64
struct
и anonymous struct
interface{}
time.Time
- по умолчанию с помощью RFC3339pointer
на один из вышеперечисленных типовslice
, array
map
custom types
могут переопределить любой из вышеперечисленных типов Примечание : map
, struct
и гнездование slice
являются и бесконечно.
Используйте Go Get.
go get github.com/go-playground/form
Затем импортируйте пакет форм в свой собственный код.
import "github.com/go-playground/form/v4"
.
Для разделения полей/структур. (например, structfield.field
)[index or key]
для доступа к индексу среза/массива или клавиши для карты. (например, 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 >
Декодирование
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" },
}
}
Кодирование
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 )
}
Декодер
decoder . RegisterCustomTypeFunc ( func ( vals [] string ) ( interface {}, error ) {
return time . Parse ( "2006-01-02" , vals [ 0 ])
}, time. Time {})
Дополнительное: если тип структуры зарегистрирован, функция будет вызвана только в случае URL.value для структуры, а не только поля структуры, например. url.values {"user": "name%3djoeybloggs"} будет вызывать функцию пользовательского типа с «пользователем» в качестве типа, однако url.values {"user.name": "joeybloggs"} не будет.
Энкодер
encoder . RegisterCustomTypeFunc ( func ( x interface {}) ([] string , error ) {
return [] string { x .(time. Time ). Format ( "2006-01-02" )}, nil
}, time. Time {})
Вы можете сказать форме, чтобы игнорировать поля, используя -
в теге
type MyStruct struct {
Field string `form:"-"`
}
Вы можете указать форме опустить пустые поля, используя ,omitempty
или FieldName,omitempty
в теге
type MyStruct struct {
Field string `form:",omitempty"`
Field2 string `form:"CustomFieldName,omitempty"`
}
Чтобы максимизировать совместимость с другими системами, энкодер пытается избежать использования индексов массива в url.values, если это вообще возможно.
например.
// 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" }
ПРИМЕЧАНИЕ: 1 распределение и B/OP в первых 4 декодах на самом деле являются структурой, выделяющейся при его передаче, поэтому примитивы на самом деле являются нулевым распределением.
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
Цитрицы конкурентов можно найти здесь
Вот список программного обеспечения, которое дополняет, используя эту библиотеку, декодирование.
Распределенные по лицензии MIT, см. Файл лицензии в коде для получения более подробной информации.