Function 什么';对于获取对象但可能找不到该对象的函数,什么是最好的func签名?
这是一个非常类似的问题,但重点是Go实现 假设有一个函数使用某个ID获取对象。该函数可能找不到该对象 比如:Function 什么';对于获取对象但可能找不到该对象的函数,什么是最好的func签名?,function,go,design-patterns,null,Function,Go,Design Patterns,Null,这是一个非常类似的问题,但重点是Go实现 假设有一个函数使用某个ID获取对象。该函数可能找不到该对象 比如: func FindUserByID(id int) *User { .... } 您应该如何处理找不到用户的情况 有许多模式和解决方案需要遵循。有些是常见的,有些在特定语言中是有利的 我需要选择一个适合Go(golang)的解决方案,因此我想查看所有选项,并获得关于最佳方法的反馈 Go有一些限制和一些可以帮助解决此问题的功能 备选案文1: 显而易见的解决方案是让“Find”函数
func FindUserByID(id int) *User {
....
}
您应该如何处理找不到用户的情况
有许多模式和解决方案需要遵循。有些是常见的,有些在特定语言中是有利的
我需要选择一个适合Go(golang)的解决方案,因此我想查看所有选项,并获得关于最佳方法的反馈
Go有一些限制和一些可以帮助解决此问题的功能
备选案文1:
显而易见的解决方案是让“Find”函数返回nil,以防找不到对象。正如许多人所知,返回nil是不利的,它迫使调用方检查nil,使“nil”成为“notfound”的神奇值
它起作用了。这很简单
备选案文2:
返回异常-“NotFound”。
Goland不支持例外情况。唯一的替代方法是使用函数返回错误,并检查调用方代码中的错误:
func FindUserByID(id int) (*User, error) {
...
return errors.New("NotFound")
}
func Foo() {
User, err := FindUserByID(123)
if err.Error() == "NotFound" {
...
}
...
}
由于Go不支持异常,因此以上是一种代码气味,依赖于错误字符串 备选案文3: 分离为两个不同的函数:一个将检查对象是否存在,另一个将返回它
func FindUserByID(id int) *User {
....
}
func IsExist(id int) bool {
...
}
问题是:
func FindUserByID(id int) OptionalUser {
....
}
func Foo() {
optionalUser := FindUserByID(123)
if optionalUser.IsEmpty() {
...
}
...
}
但它依赖于第三方,增加了编译的复杂性。它使遵循此模式的结构数量加倍
备选案文6:
Go支持在函数中返回多个值。因此,如果对象存在,“Find”函数也可以返回bool值
func FindUserByID(id int) (*User, bool) {
...
if /*user not found*/ {
return nil, false
}
...
}
这似乎是围棋中的一个有利方法。例如,在Go中强制转换还返回一个bool值,表示操作是否成功
我想知道什么是最好的方法,并就上述选项获得一些反馈
编辑:将用户更改为指针(更好的例子)这个问题基本上是基于观点的,因此我不太愿意回答。但这里发生的事情已经够多了,我认为这需要一个答案,而不仅仅是评论 您已经给出了6个选项,但实际上只有三个。您的6个选项中的大多数属于我的第一类。在底部,我将对你的每一个建议给出具体的评论
func FindUserByID(id string) (*User, error)
在这种情况下,您可以使用易于从来电者处检查的:
var ErrNotFound = errors.New("not found")
func FindUserByID(id string) (*User, error) {
/* couldn't find the user, so... */
return nil, ErrNotFound
}
在代码的其他地方
user, err := database.FindUserByID("1234")
if err == database.ErrNotFound {
/* behave accordingly */
}
不过,一般来说,哨兵错误不是最佳做法。通常通过接口传递错误类型更好,但这超出了本问题的范围func FindUserByID(id string) *User {
/* Couldn't find the user so... */
panic("Can't find the user!")
}
以下是我对你的6个选择的具体评论(再次:我的观点)
- 选项1:未找到时返回nil
这是不直观的。我的建议是,仅当零值(在您的情况下为nil)本身有效时才执行此操作。它可能不适合用户。可能是为了一个伯爵之类的东西func FindUserByID(id int) *User { ... if /*user not found*/ { return nil } ... }
- 选项2:返回异常 您的示例实际上只返回一个错误,而不是异常(恐慌)。返回错误是一个完全有效的选项,但不要求助于检查错误字符串。见我上面的讨论
- 选项3:一个要检查的函数,一个要检索的函数 这是非直觉的,而且很活泼。如何使用这个笨重的API并不明显,所以我会避免使用它。它也很有活力,因为无法保证在检查和检索之间没有创建新用户,或者删除现有用户
- <
func FindUserByID(id string) *User { /* Couldn't find the user so... */ panic("Can't find the user!") }