无法将errors.New(“something wrong”)(类型为error)用作返回参数中的error类型。

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

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 (
   &quot;log&quot;
   &quot;errors&quot;	
)

func main() {
	j := &amp;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 &lt; 5 {
		return &quot;fail&quot;, errors.New(&quot;something wrong&quot;)
	}
	return &quot;success&quot;, 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(&quot;something wrong&quot;) (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 (
	&quot;net/http&quot;
	&quot;path&quot;
	&quot;log&quot;
	&quot;errors&quot;
)


func Route(w http.ResponseWriter, r *http.Request) {

	
	uri := path.Dir(r.URL.Path)

	base := path.Base(r.URL.Path)
	if uri == &quot;/&quot; || (uri == &quot;/products&quot; &amp;&amp; base != &quot;products&quot;) {
		uri = path.Join(uri, base)
	}

	// initiate all types
	warehouse := Warehouse{}
	inventory := Inventory{}

	// check the request method
	if r.Method == &quot;GET&quot; {
		switch uri {
		case &quot;/warehouse&quot;:
			j := &amp;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 &lt; 5 {
		return &quot;fail&quot;, errors.New(&quot;something wrong&quot;)
	}
	return &quot;success&quot;, 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 &lt; 5 {
    return &quot;fail&quot;, errors.New(&quot;something wrong&quot;)
}

To:

if i &lt; 5 {
    return &quot;fail&quot;, fmt.Errorf(&quot;something wrong&quot;)
}

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(&quot;some error .... %#v&quot;, aValue)

I hope that will help.

huangapple
  • 本文由 发表于 2014年10月23日 17:52:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/26525520.html
匿名

发表评论

匿名网友

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

确定