Golang:恐慌:运行时错误:无效的内存地址或nil指针取消引用

When uploading a file to my go app, I encounter a panic.

 panic: runtime error: invalid memory address or nil pointer dereference
 /Users/bob/Projects/go/src/github.com/zenazn/goji/web/middleware/recoverer.go:24 (0xbaf5b)
    func.006: debug.PrintStack()
 /usr/local/go/src/pkg/runtime/panic.c:248 (0x1043d)
    panic: runtime·newstackcall(d->fn, (byte*)d->args, d->siz);
 /usr/local/go/src/pkg/runtime/panic.c:552 (0x10eed)
    panicstring: runtime·panic(err);
 /usr/local/go/src/pkg/runtime/os_darwin.c:454 (0xfb8e)
    sigpanic: runtime·panicstring("invalid memory address or nil pointer dereference");
 /usr/local/go/src/pkg/mime/multipart/multipart.go:223 (0xb6801)
    (*Reader).NextPart: if r.currentPart != nil {
 /Users/bob/Projects/go/src/github.com/app/controllers/company_sheet_controller.go:32 (0x2ee18)
    NewCompanySheet: part, err := mr.NextPart()
 /usr/local/go/src/pkg/net/http/server.go:1235 (0x44f00)
    HandlerFunc.ServeHTTP: f(w, r)
 /Users/bob/Projects/go/src/github.com/zenazn/goji/web/router.go:113 (0x6bc0a)

This method handles an upload from a multipart form, extracting the file contents and boundary data. The r.FormFile method on request is used to set file and header. And in order to pull the additional data from the post, I use r.MultipartReader. From the error description I see r is already declared as ParseMultipartForm when using r.FormFile. When executing the function with the different request methods individually, I receive no errors. r.FormFile and r.MultipartReader work fine isolated. Am I unable to mix the two request methods?

func Upload(r *http.Request) {
  file, header, err := r.FormFile("file")
  ErrorCheck(err)

  mr, err := r.MultipartReader()
  ErrorCheck(err)
  part, err := mr.NextPart()
  ErrorCheck(err)

  var b bytes.Buffer
  io.CopyN(&b, part, int64(1<<20))
  fmt.Println(b.String())
  defer file.Close()
}

You are calling FormFile() at the beginning of your function.

This calls ParseMultipartForm() (see Request.FormFile) which populates the MultipartForm field of your http.Request.

Now the documentation for MultipartReader() states that you should use MultipartReader() instead of ParseMultipartForm() if you want to process the data as stream.

Looking at the source MultipartReader() returns an error if the MultipartForm field was already set.

So to answer your question: No, you can't use both functions for the same request.

Also your

defer file.Close()

should be right after you checked for an error from FormFile(), otherwise the file won't be closed before Garbage Collection, when your function panics.