英文:
Golang pass nil as optional argument to a function?
问题
在Golang中,http.NewRequest
的规范如下:
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
然而,如果我不想将body
传递给io.Reader
对象,我可以将nil
作为body
选项传递,像这样:
req, err := http.NewRequest("GET", "http://www.blahblah.org", nil)
我该如何在我的代码中实现这个功能?我有一个函数,我想传递一个可选的字符串值,以便它可以通过API结果进行分页,但是如果我将nil
传递给字符串输入,我会得到以下错误:
./snippets.go:32: cannot convert nil to type string
我的函数参数如下所示:
func getChallenges(after string) ([]challenge, string, error)
请注意,这只是一个翻译,我不会回答关于代码实现的问题。
英文:
In Golang, http.NewRequest
has a specification like this:
func NewRequest(method, urlStr string, body io.Reader) (*Request, error)
However, I can pass nil
as the body
option if I don't want to pass the body
to an io.Reader
object, like this:
req, err := http.NewRequest("GET", "http://www.blahblah.org", nil)
How do I implement this functionality in my code? I have a function that I want to pass an optional string value so that it can page through API results however if I pass a nil
to the string input I get this:
>./snippets.go:32: cannot convert nil to type string
The parameters for my function look like this:
func getChallenges(after string) ([]challenge, string, error)
答案1
得分: 14
Go语言中没有“可选”参数的概念,这在其他语言中通常是可以理解的;nil
只是接口类型(在这种情况下是io.Reader
)的零值。
字符串的零值是空字符串:
getChallenges("")
如果你想接受0个或多个相同类型的参数,可以使用可变参数语法:
func getChallenges(after ...string) ([]challenge, string, error)
英文:
Go does not have "optional" arguments as a generally understood concept in other languages; nil
is just the zero value for an interface (io.Reader
in this case).
The equivalent zero value for a string is an empty string:
getChallenges("")
If you want to accept 0 or more of the same argument type, you use the variadic syntax:
func getChallenges(after ...string) ([]challenge, string, error)
答案2
得分: 11
你可以修改你的函数来接收指针值,像这样:
func getChallenges(after *string) ([]challenge, string, error)
然后你可以将nil
作为参数传递给它。但在解引用之前,不要忘记在函数内部检查after
是否为nil
值,否则会出现空指针异常:
func getChallenges(after *string) ([]challenge, string, error) {
if after == nil {
// 未指定值
} else {
fmt.Printf("After: %s\n", *after) // 注意使用"*"进行指针解引用
}
// ...
}
另一种选择:
只需使用两个函数:
func getChallenges(after string) {}
func getAllChallenges() {
return getChallenges(/* 这里填写一些默认值 */)
}
英文:
You can modify you function to receive pointer value, like this:
func getChallenges(after *string) ([]challenge, string, error)
Then you can pass nil
as an argument to it. But don't forget to check after
for nil
value inside your function before dereferencing it, or you will get a nil pointer exception:
func getChallenges(after *string) ([]challenge, string, error) {
if after == nil {
// No value specified
} else {
fmt.Printf("After: %s\n", *after) // Note pointer dereferencing with "*"
}
// ...
}
Another option:
Just use two functions:
func getChallenges(after string) {}
func getAllChallenges() {
return getChallenges(/* some default value here */)
}
答案3
得分: 4
你可以使用省略号运算符来传递可选参数... 在可选参数中不传递任何内容,并检查参数的长度。
这样应该可以解决你的问题。
func foo(params ...int) {
fmt.Println(len(params))
}
func main() {
foo()
foo(1)
foo(1,2,3)
}
英文:
you can use ellipse operator to send the optional parameters.. don't pass anything in optional parameter and check the length of parameter.
it should solve your problem
func foo(params ...int) {
fmt.Println(len(params))
}
func main() {
foo()
foo(1)
foo(1,2,3)
}
答案4
得分: 0
也许可以将它包装在一个 struct
中?
type NilableString struct {
value string;
}
英文:
Maybe wrap it in a struct
?
type NilableString struct {
value string;
}
答案5
得分: 0
以下是翻译好的内容:
这里是这样的函数如何接受nil以及值。
req, err := http.NewRequest(method, path, reader)
reader应该接受io.Reader
或nil
package io
type Reader struct {
......
}
func (r Reader) getData() []byte {
......
}
type ReaderInterface interface {
getData() []byte
}
package http
import "io"
func NewRequest(method string, path string, reader ReaderInterface) {
if (reader != nil) {
data := reader.getData()
}
......
}
请注意,NewRequest
期望的类型是ReaderInterface
而不是Reader
本身。任何具有类似上述的getData
函数的类型或nil都将被接受。在内部,您可以检查reader是否不为nil。
英文:
Here is how such functions accept nil as well as value.
req, err := http.NewRequest(method, path, reader)
reader should accept io.Reader
or nil
packege io
type Reader struct {
.....
}
func (r Reader) getData() []byte {
......
}
type ReaderInterface interface {
getDate() []byte
}
package http
import "io"
func NewRequest(method string, path string, reader ReaderInterface) {
if (reader != nil) {
data := reader.getData()
}
.....
}
Note that NewRequest
expecting type ReaderInterface but not Reader itself. Any type with GetData function like above or nil will be accepted. Inside you can check if reader is not nil.
答案6
得分: -1
你可以使用反射(reflect)。
实际上,io.Reader
是一个接口(interface)。
所以你可以定义一个签名,像这样:func getChallenges(after interface{}) ([]challenge, string, error)
interface{}
是一个空接口,可以表示任何类型。
但是我建议你使用语法 args...
来传递切片(slice),可以参考 fmt.Printf
的实现方式,因为如果你不传递字符串,切片的长度将为0,
这样可以避免使用反射,因为我认为反射对于你的函数来说太重了。
英文:
You can use reflect.
In fact io.Reader
is a interface.
So you can define signature like func getChallenges(after interface{}) ([]challenge, string, error)
interface{} is a empty interface, that is interface for anything.
But I suggest you use syntax args...
to pass slice , refer to fmt.Printf
implementation for usage, because if you pass no string the slice len is 0 and
this will avoid the reflect which I think too heavy for your function.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论