golang ,获取一条记录,数据库找不到记录,是返回 error 还是 返回对象 nil , error 也返回 nill
比如用用户 ID 获取用户资料
我是返回一个特殊的 error
func (* UserModel) GetUser(uid uint) user User, err error {
....
return user, ErrorNotFound
}
还是返回 nil, nil
func (* UserModel) GetUser(uid uint) user *User, err error {
....
return nil, nil
}
1
ryanking8215 2016-07-29 13:03:19 +08:00
我选 nil, nil
|
2
armandinho 2016-07-29 13:11:44 +08:00
通常是这么来的。
func (* UserModel) GetUser(uid uint) user *User, err error { .... return nil, nil } func (* UserModel) MustGetUser(uid uint) user User, err error { .... return user, ErrorNotFound } |
3
void1900 OP @ryanking8215 我也喜欢 nil,nil 这种 不过我刚开始用 golang ,所以比较不确定。。
|
4
void1900 OP @armandinho 好像也可以,不过一般不会定义两个功能几乎一样的方法吧。。
|
5
leitwolf 2016-07-29 13:26:23 +08:00
user=nil,err=errors.New("user not found")
return; |
6
windy0925 2016-07-29 13:31:26 +08:00
error 应该返回 nil
|
7
cloudzhou 2016-07-29 13:32:44 +08:00
这个问题在于 GetUser 没有找到用户,到底算不算一种 error ,就看你的定义了
如果算 error ,一个比较麻烦的地方是,按照 go 的哲学,所有 error 都要明显的 check 在检测错误的时候,你还需要排除 ErrorNotFound 这种情况,就比较繁琐 |
8
zhujinliang 2016-07-29 13:39:39 +08:00 via iPhone
@armandinho
Must 开头的函数应该不返回错误,有错误就 panic |
9
yanyuan2046 2016-07-29 13:39:45 +08:00
我使用第二种,在实际项目中每个错误码都是特定的,查询错误是 ErrGetData ,数据不存在是 ErrDataNotExist ,以此类推。这个错误码不是字符串,而是一个对象
type errorCode { ID string Namespace string Code int32 Message string } |
10
huijiewei 2016-07-29 13:41:13 +08:00
返回 nil ,不管啥语言,不要在内部乱抛出异常
|
11
qwepoidjdj 2016-07-29 15:18:44 +08:00
这里看你对错误的定位
我是这样想的(做的) 看这个方法具体面对的层级 如果只是在数据库访问层级 返回 nil 肯定是比 err 合理 因为对于数据库本身来说 就是没有查到数据而不是产生了错误 但是对于业务处理层来说 可能拿到了 nil 以后需要返回一个 err 来通告操作的人 |
12
gamexg 2016-07-29 15:22:45 +08:00
nil,nil
实现简单,不用费事的区分开数据库错误还是不存在。 否则还需要定义不同的 error 来区分是数据库错误还是不存在。 |
13
evilgod528 2016-07-29 18:45:05 +08:00
mgo 是返回 ErrNotFound
|
14
evilgod528 2016-07-29 18:47:47 +08:00
如果返回 nil,nil 那么,每次得到的 user 还得检查是否 nil ,而如果你查到到的 error 为 nil 的话,那么 user 可能有值
|
15
evilgod528 2016-07-29 18:48:33 +08:00
@evilgod528 user 肯定有值,打快了,敲错字了
|
16
magicdawn 2016-07-29 19:14:53 +08:00
|
17
janxin 2016-07-29 19:30:42 +08:00
return user, ErrorNotFound
|
18
janxin 2016-07-29 19:34:53 +08:00
另外其实 golang 中的 error 是个 interface ,所以利用 @yanyuan2046 提到的错误扩展方式其实非常方便
|
19
orvice 2016-07-29 20:28:34 +08:00
nil nil
|
20
zhx1991 2016-07-29 20:50:08 +08:00
看业务.
|
21
raincious 2016-07-29 20:57:14 +08:00
我觉得这种问题没什么好纠结的。
返回 error 是考虑到后面的过程能截获这个错误然后进行处理,而标记成 Must 的函数则是这个函数出现错误之后,程序完全没必要继续运行下去了。 GetUser 找不到记录的话,应该返回 nil 指针附带一个错误,指明发生了什么(比如是什么导致无法获取用户的,是没有记录,服务器挂了,服务器拒绝处理还是其他什么)。你可以参考 Google 在自己 AppEngine 系统上的实现: https://cloud.google.com/appengine/docs/go/datastore/reference#variables 当 Datastore 尝试获取一个不存在的对象时,会返回 ErrNoSuchEntity 这个 error 。 |
22
aphasia 2016-07-29 23:51:59 +08:00
这个跟你业务场景,以及设计有关,建议用 2 ,否则给自己留坑,不信你试试
如果用 2 的话,可以在调用函数时区分出到底是同 db 交互失败,还是交互成功但却查询为空,可以在调用时区别地对待这两种结果…… 不信你试试 1 …… |
23
julor 2016-07-30 07:44:11 +08:00 via Android
查询结果为空,返回 not found ,与数据交互出现的无知,直接返回上级错误
|
25
darasion 2016-08-01 08:27:04 +08:00
我认为,
如果系统其他部分可能会报错,比如数据库可能连接不上, cache 可能挂了什么的,那返回值就需要第二个 error 参数 如果系统其他部分根本不可能报错,就是一个普普通通的数据类型,没有跟其他系统交互,那么就没有第二个 error 返回,找不到就直接一个 nil 就好了, nil 本身就是找不到的意思,互为充分必要条件。 至于返回是否是 nil 的检查,我想应该适当的抛给上层逻辑来处理。具体情况具体分析。 |
26
leedstyh 2016-08-01 17:04:16 +08:00
我也纠结过,现在的做法是:
定义一个`UserNotFound`的空 User struct ,如果查询没有结果,就返回`UserNotFound, nil`。 给 User 这个 struct 定义一个`IsNil()`的方法,一般来说用户名不能为空,所以就根据用户名来判断这个 user 是不是存在 handler 里,如果`user.IsNil()`结果是 true ,就返回 404 |