Golang表单编码嵌套结构

I am using ajg/form package to marshal my nested struct to url encoded data.

package main
import (
    "fmt"
    "bytes"
    "github.com/ajg/form"
)
type Subject struct {
    SubjectTag      string `form:"tag,omitempty"`
    SubjectName    string `form:"name,omitempty"`
}
type Student struct {
    Name          string `form:"stud_name,omitempty"`
    SubjectList   []Subject `form:"subjects,omitempty"`
}
func main() {
    student := Student{
        Name: "newStudent",
        SubjectList: []Subject{
            {SubjectTag:  "mathstag", SubjectName: "maths"},
            {SubjectTag:  "englishtag", SubjectName: "english"},
        },
    }
    runParse(student)
}
func runParse(i interface{}) {
    buf := new(bytes.Buffer)
    form.NewEncoder(buf).Encode(i)
    body := buf.String()
    fmt.Printf("Body: %#v
", body) 
    // Prints Body: "subjects.0.name=maths&subjects.0.tag=mathstag&subjects.1.name=english&subjects.1.tag=englishtag&stud_name=newStudent"
    //After this I create an HTTP request client, and send a POST request with this body to a server.
}

Problem is my server doesn't understand dot delimited POST body, but it does understand the body in this format - "subjects[0][name]=maths&subjects[0][tag]=mathstag&subjects[1][name]=english&subjects[1][tag]=englishtag&stud_name=newStudent", which I have tested with Postman. How can I create a body like this using above struct? Is there any other package I can use?

The ajg/form package isn't designed to easily do that. form.go in package form defines constant defaultDelimiter to be the period/dot (.) rune. That's then used in encode.go and decode.go in the same package, set as a field value in the Encoder struct, and then passed in as an argument in calls to methods in node.go.

You can easily override the default delimiter with a different character, specified as rune r here:

encoder := form.NewEncoder(buf)
encoder.DelimitWith(r)

Will change the delimiter from dot to whatever you specify as rune r.

Going beyond that would require overriding several methods, probably by creating intermediary types with the original types embedded in them, and then defining overriding functions where needed. For example, line 27 in node.go:

y.merge(d, e, p+escape(d, e, k)+string(d), vs)

Would have to be changed so it doesn't just concatenate the delimiter, d, but rather surrounds with braces (or parens, or quotes, or whatever you set it to use, as it would be best if that were configurable).

You can get a good idea of which areas of the code need to be changed by looking at this diff from when ajg added support for custom delimiters and escapes: https://github.com/ajg/form/commit/66a87187c6cd884319abb7b97b623e9bb30e075b

If you don't want to take on all those new types and method overrides, you could write your own code to convert the ajg/form package output to the format you need, or look into configuring/updating your server to recognize a single-character-delimited format.

If a server-side fix isn't easily available, then even better would be to fork/clone the ajg/form repository, add optional left + right enclosing delimiter support, and submit a pull request after you get it working.