
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 |