一个 post 请求里面的数值类型传递 0 和不传递,解析到结构体中都是 0,要怎么判断是否传递了呢
1
Vegetable 2019-01-29 17:09:35 +08:00
专门要判断的话就先赋值改动默认值.比如-1,应该能解决.
|
2
Immortal 2019-01-29 17:12:21 +08:00
解析前判断
|
4
xkeyideal 2019-01-29 17:22:57 +08:00
指针,我去翻个例子给你
|
5
lyatqh 2019-01-29 17:23:00 +08:00
值类型改成指针类型就可以了;比如 int 类型改成*int,如果不传是 nil 而不是 0。
也可以用这个库 https://github.com/mattn/go-nulltype |
6
xkeyideal 2019-01-29 17:24:25 +08:00 2
type NodeXXX struct {
Date string `json:"date"` Count *int32 `json:"count"` } |
7
justfly 2019-01-29 17:26:51 +08:00
你这个需求,只能别解析到结构体里面,解析到 map 里面了
|
8
GuangXiN 2019-01-29 17:28:55 +08:00
```go
func myHandler(w http.ResponseWriter,r *http.Request) { err := r.ParseForm() if err != nil { panic(err) } value, ok := r.PostForm["some_field"]; if !ok { // some_field 不存在 } // ... } ``` |
9
GuangXiN 2019-01-29 17:30:12 +08:00
原来 V2EX 不支持 markdown 语法么
|
10
Immortal 2019-01-29 17:30:13 +08:00
8l 那样的
解析前默认就是在 request 的 map 里的 |
12
Immortal 2019-01-29 17:48:17 +08:00
json 看 6l
|
13
strive 2019-01-29 17:55:04 +08:00
//GetInt 获取 int 数据,不是有效的数字则返回默然值或 0,默认值传-1
func GetInt(v interface{}, def ...int) int { value := fmt.Sprintf("%v", v) if strings.Contains(strings.ToUpper(value), "E+") { var n float64 _, err := fmt.Sscanf(value, "%e", &n) if err == nil { return int(n) } if len(def) > 0 { return def[0] } } if value, err := strconv.Atoi(value); err == nil { return value } if len(def) > 0 { return def[0] } return 0 } |
15
Muninn 2019-01-29 18:30:54 +08:00
目前主流的有两种办法
一种是 gin 推荐的用一个校验的 package 去做。 在结构体上用 tag 描述校验规则,如果不让为空可以直接报错。 但是这个其实达不到有些目的。 我是用的额外的结构体+指针类型。 根据是否是 nil 决定怎么赋值。 |
16
Muninn 2019-01-29 18:32:06 +08:00
|
18
rayhy 2019-01-29 18:35:37 +08:00
啊我最近写项目也遇到这个问题了!确实搞起来有点麻烦,但好在有人已经写好库了,我最近一直用: https://godoc.org/gopkg.in/guregu/null.v3
思路是这样: 新建一个 struct, type NullInt64 struct { Int64 int64 Valid bool // Valid is true if Int64 is not NULL } 然后给这个 struct 实现 解析 json 时需要的 MarshalJSON 那一套方法。 最终代码如下可以参考: https://github.com/RayHY/go-isso/blob/master/internal/app/isso/server/handlers.go#L232 |
19
katsusan 2019-01-29 18:37:42 +08:00
stackoverflow 上看到一种方法:
对承载 Unmarsha 结果的对象设定一个不可能的默认值。 ``` var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"} ]`) type Animal struct { Name string Order string ID int } animals := &Animal{ID: -9999} err := json.Unmarshal(jsonBlob, animals) if err != nil { fmt.Println("error:", err) } fmt.Printf("%+v", animals) ``` 原文: https://stackoverflow.com/questions/39160807/default-value-golang-struct-using-encoding-json |
20
rayhy 2019-01-29 18:41:14 +08:00
@rayhy
其实使用一个新的 struct 代替原来的类型是最实在的方法了,不 hack,很通用,最关键是这些类型也可以在 sql 库里面使用,用来区分 0 值和不存在。 简单的说就是这个: https://godoc.org/gopkg.in/guregu/null.v3#Int.UnmarshalJSON UnmarshalJSON implements json.Unmarshaler. It supports number and null input. 0 will not be considered a null Int. It also supports unmarshalling a sql.NullInt64. |
21
est 2019-01-29 19:02:35 +08:00
每次有人说强类型语言方便,我就想举这个例子。
|
22
kimown 2019-01-29 19:13:07 +08:00 via Android 1
简直了,go 一天到晚都在解决接受数据是什么的问题?
|
23
WilliamYang 2019-01-29 19:17:24 +08:00
我也想知道目前最好的解决办法, 我之前用了另外一个字段来标记是否有传入值, 觉得用指针好像不太优雅
|
25
ck65 2019-01-30 00:37:04 +08:00
指针 +1
|
27
justfly 2019-01-30 10:21:22 +08:00
@123string POST body 中的数据一般不外乎 multipart form,url 编码的数据 和 json,这几类都可以在拿到 request body 之后进行解析,前两个 golang 标准库中本身就有,其实现就是个 map,json 解析到 map 直接 json.Unmarshal 就可以,文档里面有示例。
|
28
yimiao 2019-01-30 15:03:51 +08:00
如果使用 新的 struct int*来接受数据,然后又要做一道赋值转化到另外一个 struct int ?好像很多 orm 不支持 int*是主键的额?
|
29
soulsxd 2019-01-30 16:16:07 +08:00
解析前赋值其它值
|
30
dongisking 2019-01-30 17:10:46 +08:00
|