英文:
go generate: stringer: invalid operation: has no field or method String
问题
我正在尝试使用[stringer][1]命令来为一些int类型生成String()方法。以下是代码的样子:
//go:generate stringer -type=MyIntType
type MyIntType int
const (
resource MyIntType = iota
)
func myfunc() {
print(resource.String())
}
在执行go generate命令时,我遇到了错误:“invalid operation: resource (constant 0 of type MyIntType) has no field or method String”。这是有道理的,因为还没有String方法。如果stringer命令应该生成String方法,我应该如何修复这个错误呢?我是否应该在代码中到处使用fmt.Sprintf("%s", resource)?但这看起来有点丑陋,至少没有resource.String()那么方便。
[1]: https://godoc.org/golang.org/x/tools/cmd/stringer
英文:
I'm trying to use the [stringer][1] cmd so that I can generate String() methods for some int types. Here is how the code looks like
//go:generate stringer -type=MyIntType
type MyIntType int
const (
resource MyIntType = iota
)
func myfunc(){
print(resource.String())
}
The error I'm getting on go generate command is invalid operation: resource (constant 0 of type MyIntType) has no field or method String
which makes sense because there is no String method yet. How am I supposed to fix this error if stringer cmd is supposed to actually generate the String method? Should I use fmt.Sprintf("%s", resource) all over the code ? it looks a bit ugly to me. At least not as nice as resource.String().
[1]: https://godoc.org/golang.org/x/tools/cmd/stringer
答案1
得分: 0
每个文件在生成方法之前都必须由types
库进行解析和类型检查。这通常不会造成问题,因为String()
方法很少直接调用,而是通过将值传递给像fmt.Println
这样的函数来使用,该函数总是首先检查是否存在Stringer
。
你可以选择不自己调用String()
:
文件:type.go
//go:generate stringer -type=MyIntType
package painkiller
import "fmt"
type MyIntType int
const (
resource MyIntType = iota
)
func myfunc() {
fmt.Println(resource)
}
或者你可以将调用放在另一个文件中,并仅将stringer需要的文件作为参数传递。如果没有参数,stringer会检查整个包,但如果你只提供文件列表,它们会假设某些方法可能在未提供的文件中定义。
文件:type.go
//go:generate stringer -type=MyIntType type.go
package foo
type MyIntType int
const (
resource MyIntType = iota
)
文件:myfunc.go
package foo
func myfunc() {
print(resource.String())
}
英文:
Each file must be parsed and type checked by the types
library before the methods are generated. This usually doesn't pose a problem, since the String()
method is rarely called directly, and is used by passing a value to something like fmt.Println
that always checks first for a Stringer
.
You can either not call String()
yourself:
file: type.go
//go:generate stringer -type=MyIntType
package painkiller
import "fmt"
type MyIntType int
const (
resource MyIntType = iota
)
func myfunc() {
fmt.Println(resource)
}
Or you can put the calls in another file, and pass only the files that stringer needs as arguments. With no arguments, stringer checks the package as a whole, but if you provide only a list of files, they assume that some methods may be defined in files not provided.
file: type.go
//go:generate stringer -type=MyIntType type.go
package foo
type MyIntType int
const (
resource MyIntType = iota
)
file myfunc.go
package foo
func myfunc() {
print(resource.String())
}
答案2
得分: 0
字符串命令调用go/parser.ParseFile来处理每个Go文件。因此,如果你有一个未声明的方法,它将失败。你需要使用fmt.Sprint*语句来解决这个问题。或者你可以告诉go generate只生成特定的文件。
我不知道我们是否可以将这个称为一个bug。你可以提交一个bug报告,看看会得到什么样的回应。
英文:
The stringer cmd calls the go/parser.ParseFile for every go file. Thus if you have a method that is not declared it will fail. You will have to use fmt.Sprint* statements to get over this. Or you could tell go generate to only generate a specific file.
I don't know if we could term this as a bug. You could file it, probably see what the response is.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论