go generate: stringer: 无效操作:没有字段或方法 String

huangapple go评论73阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2015年3月1日 19:15:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/28792884.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定