英文:
Cannot use errors.New("something wrong") (type error) as type error in return argument
问题
我有以下代码(http://play.golang.org/p/47rvtGqGFn)。它在playground上运行正常,但在我的系统上失败了。
package main
import (
"log"
"errors"
)
func main() {
j := &JustForTest{}
a, err := j.Test(3)
if err != nil {
log.Println(err)
}
log.Println(a)
}
type JustForTest struct {}
func (j *JustForTest) Test(i int) (string, error) {
if i < 5 {
return "fail", errors.New("something wrong")
}
return "success", nil
}
在playground上,它返回了我期望的结果:
2009/11/10 23:00:00 something wrong
2009/11/10 23:00:00 fail
但是当我在我的系统上运行"go install"时,我得到了编译错误:
../warehouse/warehouse.go:32: cannot convert nil to type error
../warehouse/warehouse.go:83: cannot use errors.New("something wrong") (type error) as type error in return argument
../warehouse/warehouse.go:85: cannot use nil as type error in return argument
我觉得这真的很奇怪。我已经将Go从1.3.2升级到1.3.3,但仍然遇到相同的错误。我的系统可能出了什么问题?
更新:
这是我的本地代码:
package warehouse
import (
"net/http"
"path"
"log"
"errors"
)
func Route(w http.ResponseWriter, r *http.Request) {
uri := path.Dir(r.URL.Path)
base := path.Base(r.URL.Path)
if uri == "/" || (uri == "/products" && base != "products") {
uri = path.Join(uri, base)
}
// initiate all types
warehouse := Warehouse{}
inventory := Inventory{}
// check the request method
if r.Method == "GET" {
switch uri {
case "/warehouse":
j := &JustForTest{} // This is the troubled code
a, err := j.Test(3)
if err != nil {
log.Println(err)
}
log.Println(a)
...
}
}
type JustForTest struct {}
func (j *JustForTest) Test(i int) (string, error) {
if i < 5 {
return "fail", errors.New("something wrong")
}
return "success", nil
}
我发现当我运行这段代码时,我得到了错误。但是当我编写一个新的包,并且只写与playground中完全相同的代码时,它可以正常工作。我不明白为什么会发生这种情况。有什么建议吗?
英文:
i have the following code (http://play.golang.org/p/47rvtGqGFn). it works on playground but fail on my system
package main
import (
"log"
"errors"
)
func main() {
j := &JustForTest{}
a, err := j.Test(3)
if err != nil {
log.Println(err)
}
log.Println(a)
}
type JustForTest struct {}
func (j *JustForTest) Test(i int) (string, error) {
if i < 5 {
return "fail", errors.New("something wrong")
}
return "success", nil
}
in playground it return something i expected :
2009/11/10 23:00:00 something wrong
2009/11/10 23:00:00 fail
But when I run "go install" on my system, I get compiler error :
../warehouse/warehouse.go:32: cannot convert nil to type error
../warehouse/warehouse.go:83: cannot use errors.New("something wrong") (type error) as type error in return argument
../warehouse/warehouse.go:85: cannot use nil as type error in return argument
I feel this is really weird. I have upgrade my Go installation from 1.3.2 to 1.3.3 but still i get the same error. What could possibly wrong with my system?
UPDATE:
Here's my local code :
package warehouse
import (
"net/http"
"path"
"log"
"errors"
)
func Route(w http.ResponseWriter, r *http.Request) {
uri := path.Dir(r.URL.Path)
base := path.Base(r.URL.Path)
if uri == "/" || (uri == "/products" && base != "products") {
uri = path.Join(uri, base)
}
// initiate all types
warehouse := Warehouse{}
inventory := Inventory{}
// check the request method
if r.Method == "GET" {
switch uri {
case "/warehouse":
j := &JustForTest{} // This is the troubled code
a, err := j.Test(3)
if err != nil {
log.Println(err)
}
log.Println(a)
...
}
}
type JustForTest struct {}
func (j *JustForTest) Test(i int) (string, error) {
if i < 5 {
return "fail", errors.New("something wrong")
}
return "success", nil
}
I found that when i run this code, I get the error. But when I write a new fresh package and just write the exactly the same code as i did in the plaground. it works. I don't understand why this is happening. any advice guys?
答案1
得分: 2
似乎你在你的包中定义了一个名为error
的类型。
这导致了与内置的error
类型的名称冲突(你的包定义的类型遮蔽了内置类型),因此你看到了令人困惑的错误消息。
为你包中的类型使用一个不同的、更具描述性(不那么通用)的名称。
英文:
It seems like you have defined a type called error
in your package.
That's causing a name-collision with the built-in error
type (your package-defined type shadows the built-in type) and hence the confusing error message you're seeing.
Use a different, more descriptive (less-general) name for your package's type.
答案2
得分: 2
除了@tomwilde的回答之外,我建议使用fmt.Errorf()
函数来构建错误。您还需要添加对"fmt"包的导入,并可以删除对"errors"包的导入。
您的代码可以改为:
if i < 5 {
return "fail", fmt.Errorf("something wrong")
}
使用fmt.Errorf()
的优点是您可以提供格式化来构建错误消息,这在将来可能非常方便,例如fmt.Errorf("some error .... %#v", aValue)
。
希望这能帮到您。
英文:
In addition to @tomwilde response, I would recommend using fmt.Errorf()
function to build errors. You would also need to add import of "fmt" package and could remove import of "errors" package.
Your code could be changed from:
if i < 5 {
return "fail", errors.New("something wrong")
}
To:
if i < 5 {
return "fail", fmt.Errorf("something wrong")
}
Advantage of using fmt.Errorf()
approach is that you can also provide formatting to build your error message, which might be very handy in the future e.g. fmt.Errorf("some error .... %#v", aValue)
I hope that will help.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论