Golang是否将nil作为可选参数传递给函数?
在Golang中,Golang是否将nil作为可选参数传递给函数?,go,Go,在Golang中,http.NewRequest有如下规范: func NewRequest(method, urlStr string, body io.Reader) (*Request, error) req, err := http.NewRequest("GET", "http://www.blahblah.org", nil) func getChallenges(after string) ([]challenge, string, error) 但是,如果我不想将body传
http.NewRequest
有如下规范:
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
req, err := http.NewRequest("GET", "http://www.blahblah.org", nil)
func getChallenges(after string) ([]challenge, string, error)
但是,如果我不想将body
传递给io.Reader
对象,我可以将nil
作为body
选项传递,如下所示:
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
req, err := http.NewRequest("GET", "http://www.blahblah.org", nil)
func getChallenges(after string) ([]challenge, string, error)
如何在代码中实现此功能?我有一个函数,我想传递一个可选的字符串值,以便它可以通过API结果进行分页,但是如果我将nil
传递给字符串输入,我会得到以下结果:
./snippets.go:32:无法将nil转换为字符串类型
my函数的参数如下所示:
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
req, err := http.NewRequest("GET", "http://www.blahblah.org", nil)
func getChallenges(after string) ([]challenge, string, error)
Go在其他语言中没有“可选”参数作为一个普遍理解的概念nil
只是接口的零值(io.Reader
)
字符串的等效零值为空字符串:
getChallenges("")
如果要接受0或更多相同参数类型,请使用可变语法:
func getChallenges(after ...string) ([]challenge, string, error)
您可以使用reflect。
实际上,io.Reader
是一个接口
因此,您可以定义签名,如func-getChallenges(在接口{}之后)([]质询,字符串,错误)
接口{}是一个空接口,即任何对象的接口
但是我建议您使用语法args…
来传递slice,请参阅fmt.Printf
实现以了解用法,因为如果您不传递字符串,slice len为0和
这将避免反射,我认为反射对您的功能来说太重。您可以使用椭圆运算符发送可选参数。。不要在可选参数中传递任何内容,并检查参数的长度。 它应该能解决你的问题
func foo(params ...int) {
fmt.Println(len(params))
}
func main() {
foo()
foo(1)
foo(1,2,3)
}
您可以修改函数以接收指针值,如下所示:
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
req, err := http.NewRequest("GET", "http://www.blahblah.org", nil)
func getChallenges(after string) ([]challenge, string, error)
func-getChallenges(在*string之后)([]质询,字符串,错误)
然后可以将nil
作为参数传递给它。但是,在取消引用函数之前,不要忘记在函数中检查之后的是否有nil
值,否则会出现nil指针异常:
func getChallenges(after *string) ([]challenge, string, error) {
if after == nil {
// No value specified
} else {
fmt.Printf("After: %s\n", *after) // Note pointer dereferencing with "*"
}
// ...
}
另一个选项:
只需使用两个功能:
func getChallenges(after string) {}
func getAllChallenges() {
return getChallenges(/* some default value here */)
}
也许把它包装在一个结构中
类型NilableString结构{
值字符串;
}
我使用的是空字符串“”,不过我要实现可变语法。我假设这类似于python中的*arg/**kwargs。干杯Go确实有可选参数,带有variadics。@MikeSchinkel:variadics是variadics,我在答案中指出它们是一种可能的解决方案。因为go语言规范没有定义“可选参数”,所以您需要借用其他语言的定义,比如python或ruby,这些是不同的概念,因为它们也有可变参数,这一点更加明显。在定义和描述编程概念时,使用的语言的精确性是非常重要的。我非常同意使用精确的语言是重要的,这就是我评论的原因。您的语句“Go中的任何参数都是“可选的”;“可能会被错误读取。如果不传递命名参数,则无法调用函数。”。如果你说“Go没有其他语言中普遍理解的“可选”参数”,那么我就不会发表评论了。或者,如果您以“Go中没有参数是“可选的”,但Go确实有变量”开头,我也不会发表评论,因为您在结尾提到变量会受到常见的#tldr代码>网络上的问题。@MikeSchinkel:关于第一行的语义,这是一个足够公平的评论,可能只是在文章中作为编辑提交的(毕竟这是公认的做法)。将参数设置为*字符串的一个巨大缺点是,您不能获取字符串文本的地址,它也不会自动为您装箱字符串。“just add another function”参数可能导致处理多个排列所需的方法激增,需要为这些方法确定有意义、可发现和可记忆的名称,并增加学习使用更多方法而不是更少方法的包的负担#jmtcw