golang 怎么判断是否传递了数值类型

2019-01-29 17:02:09 +08:00
 123string

一个 post 请求里面的数值类型传递 0 和不传递,解析到结构体中都是 0,要怎么判断是否传递了呢

5056 次点击
所在节点    Go 编程语言
30 条回复
Vegetable
2019-01-29 17:09:35 +08:00
专门要判断的话就先赋值改动默认值.比如-1,应该能解决.
Immortal
2019-01-29 17:12:21 +08:00
解析前判断
123string
2019-01-29 17:19:26 +08:00
@Immortal 解析前怎么判断
xkeyideal
2019-01-29 17:22:57 +08:00
指针,我去翻个例子给你
lyatqh
2019-01-29 17:23:00 +08:00
值类型改成指针类型就可以了;比如 int 类型改成*int,如果不传是 nil 而不是 0。
也可以用这个库 https://github.com/mattn/go-nulltype
xkeyideal
2019-01-29 17:24:25 +08:00
type NodeXXX struct {
Date string `json:"date"`
Count *int32 `json:"count"`
}
justfly
2019-01-29 17:26:51 +08:00
你这个需求,只能别解析到结构体里面,解析到 map 里面了
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 不存在
}
// ...
}
```
GuangXiN
2019-01-29 17:30:12 +08:00
原来 V2EX 不支持 markdown 语法么
Immortal
2019-01-29 17:30:13 +08:00
8l 那样的
解析前默认就是在 request 的 map 里的
123string
2019-01-29 17:46:20 +08:00
@GuangXiN json 格式的
Immortal
2019-01-29 17:48:17 +08:00
json 看 6l
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
}
123string
2019-01-29 18:16:54 +08:00
@justfly 解析到 map 怎么解析的?
Muninn
2019-01-29 18:30:54 +08:00
目前主流的有两种办法

一种是 gin 推荐的用一个校验的 package 去做。 在结构体上用 tag 描述校验规则,如果不让为空可以直接报错。 但是这个其实达不到有些目的。

我是用的额外的结构体+指针类型。 根据是否是 nil 决定怎么赋值。
Muninn
2019-01-29 18:32:06 +08:00
123string
2019-01-29 18:33:53 +08:00
@Muninn 谢谢
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
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
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.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/531648

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX