使用具有映射数据的结构体

huangapple go评论75阅读模式
英文:

Using a struct with map data

问题

我相对于Go语言还比较新手,我在使用结构体处理POST数据方面遇到了困难。我想要做的是提交一个表单,然后将该表单提交到MongoDB(我还没有做到这一步)。我无法弄清楚如何将这个表单数据与结构体一起使用。

package main

import "net/http"

type Paste struct {
  Title    string
  Content  string
  Language string
  Expires  int
  Created  int64
}

func index(w http.ResponseWriter, r *http.Request) {
  if r.Method == "POST" {
    r.ParseForm()
  
    // r.Form = map[title:[Wadup] content:[Brother]]
  }
}

func main() {
  http.HandleFunc("/", index)
  http.ListenAndServe(":1234", nil)
}

基本上,我想要做的是将map的值插入到结构体中,而不是手动分配所有的值,就像你在这里看到的一样:p := Paste{Title: r.Form["title"]}

英文:

I'm relatively new to Go, I'm struggling to get my head around using POST data with structs. What I essentially want to do is submit a form, then submit that form to MongoDB (haven't got that far yet). I can't work out how to use this form data with a struct.

package main

import "net/http"

type Paste struct {
  Title    string
  Content  string
  Language string
  Expires  int
  Created  int64
}

func index(w http.ResponseWriter, r *http.Request) {
  if r.Method == "POST" {
    r.ParseForm()
  
    // r.Form = map[title:[Wadup] content:[Brother]]
  }
}

func main() {
  http.HandleFunc("/", index)
  http.ListenAndServe(":1234", nil)
}

What I basically want to do is insert the map values into the struct, without manually assigning all of them, like you can see here: p := Paste{Title: r.Form["title"]}

答案1

得分: 0

在调用r.ParseForm()之后,你可以访问r.Form,它保存了解析后的表单数据的map[string][]string。你可以通过使用键(表单字段名)来访问这个映射:

r.ParseForm()
form := r.Form

someField := form["someField"]
anotherField := form["anotherField"]

或者遍历所有可用的键/值:

r.ParseForm()
form := r.Form

for key, value := range form {
  fmt.Println("Key:", key, "Value:", value)
}

更新

如果你想要一个更通用的解决方案,可以看一下reflect包。这只是一个简单的示例:

v := url.Values{}
v.Set("Title", "Your Title")
v.Set("Content", "Your Content")
v.Set("Language", "English")
v.Set("Expires", "2015")
v.Set("Created", "2014")

paste := Paste{}
ps := reflect.ValueOf(&paste)
s := ps.Elem()

for key, value := range v {
    f := s.FieldByName(key)
    if f.IsValid() && f.CanSet() {
        switch f.Kind() {
        case reflect.String:
            f.SetString(value[0])
        case reflect.Int64:
            i, _ := strconv.ParseInt(value[0], 0, 64)
            f.SetInt(i)
        }
    }
}

Play

英文:

After you called r.ParseForm() you can access r.Form which holds a map[string][]string of the parsed form data. This map can be accessed by using keys (your form field names):

r.ParseForm()
form := r.Form

someField := form["someField"]
anotherField := form["anotherField"]

or loop through all available keys/ values:

r.ParseForm()
form := r.Form

for key, value := range form {
  fmt.Println("Key:", key, "Value:", value)
}

Update

In case you want a more generic solution take a look at the reflect package. Just to give you a rough example it could look like this:

v := url.Values{}
v.Set("Title", "Your Title")
v.Set("Content", "Your Content")
v.Set("Language", "English")
v.Set("Expires", "2015")
v.Set("Created", "2014")

paste := Paste{}
ps := reflect.ValueOf(&paste)
s := ps.Elem()

for key, value := range v {
	f := s.FieldByName(key)
	if f.IsValid() && f.CanSet() {
		switch f.Kind() {
		case reflect.String:
			f.SetString(value[0])
		case reflect.Int64:
			i, _ := strconv.ParseInt(value[0], 0, 64)
			f.SetInt(i)
		}
	}
}

Play

答案2

得分: 0

使用gorilla/schema库,该库专为此用例而构建:

package main

import (
    "net/http"
    "github.com/gorilla/schema"
)

type Paste struct {
    Title    string
    Content  string
    Language string
    Expires  int
    Created  int64
}

var decoder = schema.NewDecoder()

func index(w http.ResponseWriter, r *http.Request) {

    err := r.ParseForm()
    // 处理错误

    var paste = &Paste{}

    err := decoder.Decode(paste, r.PostForm)
    // 处理错误

}
英文:

Use gorilla/schema, which was built for this use-case:

package main

import(
    "net/http"
    "github.com/gorilla/schema"
)

type Paste struct {
  Title    string
  Content  string
  Language string
  Expires  int
  Created  int64
}

var decoder = schema.NewDecoder()

func index(w http.ResponseWriter, r *http.Request) {
  
    err := r.ParseForm()
    // handle error

    var paste = &Paste{}

    err := decoder.Decode(paste, r.PostForm)
    // handle error

}

huangapple
  • 本文由 发表于 2014年5月10日 00:26:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/23569606.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定