1

I am a new hand come from Java to Go

Look at my codes

package utils

import "os"

type FileController struct{
    file *os.File
}

func (c *FileController)OpenFile(path string)error{
    c.file, err := os.OpenFile(path,os.O_CREATE | os.O_RDWR,0755)

    //return some value these
}

I want to open a file but this not works

Goland tell me Unresolved reference 'err'

If I init err first, I write follow codes

var err error
c.file, err = os.OpenFile(path,os.O_CREATE | os.O_RDWR,0755)

Goland also tell me Unused variable 'err'

But if I use

f, err := os.OpenFile(path,os.O_CREATE | os.O_RDWR,0755)
c.file = f
_ = err

I works

I think := will works at least have a un-declaration variable in left

c.file already been inited, err a new variable.

Should I must use second way?

I feel that the first way is not elegant.


Update-1

When I use @GreatDharmatma method.

Golang tell me Unresolved variable err

enter image description here


Update-2

It's works, I not notice @GreatDharmatma return (err error)

It's my fault.

This's a Summary:

  1. := used only if all of left variable not declare before

  2. if a variable have been declared before(like c.file).

    We need pre-declare err before os.OpenFile(path,os.O_CREATE | os.O_RDWR,0755)

    var err error

  3. Another way to solve this problem is use named return value as @GreatDharmatma said.

From Golang docs

Docs-Named-variable

Go's return values may be named. If so, they are treated as variables defined at the top of the function.

Thank all of you! Have a nice day!


Update-3 After two days

From @LukeJoshuaPark comment.

Using a short variable declaration requires both variables to not be declared first" - Not true. To use a short variable declaration, at least one must not be declared

What LukeJoshuaPark is right, I ask a same in golang-nuts

My reply

For all typed object such as `type *** struct`, `type *** func()`, `type **** int`, their field cannot be redeclare? and cannot be used at left side of `:=`?

heat-heart firend said

That is correct. A member field cannot be on the left side of :=

This is the from the spec:

It is shorthand for a regular variable declaration with initializer expressions but no types:

"var" IdentifierList = ExpressionList .

So,

x, y:=values

is identical to

var x, y = values

Applying this rule to your example, it becomes:

var c.file, err=os.OpenFile...

which is not valid.

Thanks.Question Over

7
  • := is strictly used to declare variables. If you need to assign to an existing variable (like c.file) you need to use =. Commented Oct 10, 2018 at 1:21
  • And Go requires you to read every variable that is written to. If you don't plan on reading err, replace it with _ in your assignment. Commented Oct 10, 2018 at 1:21
  • Correct but using = would still cause an error because err would not be declared first to be assigned. See my answer. Commented Oct 10, 2018 at 1:22
  • 1
    You followed my answer partially. You updated the assignment operator but not the named return type. You need to use (err error) as return type and not just error. See the image in my answer. Commented Oct 10, 2018 at 1:35
  • 1
    @toffee consider reading the comments and answer very carefully. They end up explaining precisely the errors you're seeing. Commented Oct 10, 2018 at 1:36

1 Answer 1

2

The problem here is because you are using :=

Using a short variable declaration requires both variables to not be declared first. In your case c.file is declared and err is not. Hence the error. Try the following snippet instead.

func (c *FileController)OpenFile(path string)(err error){
    c.file, err = os.OpenFile(path,os.O_CREATE | os.O_RDWR,0755)

    //return some value these
}

This should work just fine

enter image description here

Sign up to request clarification or add additional context in comments.

8 Comments

In this case both c.file and err are declared before hand and you can use assignment without facing a problem.
Where err is declared? It not works, Goland tell me Unresolved reference err``, look at my updated question
err is a named return here. Take a look at your function and my function definition very carefully func (c *FileController)OpenFile(path string)error and func (c *FileController)OpenFile(path string)(err error)
Yes, It works now, if I return (err error), Did it mean "I want to return err, so please help me declare err first"? I notice you not declare err first. c.file exists, but err not.
I solve by myself about named return values, Thank you! From Go doc Go's return values may be named. If so, they are treated as variables defined at the top of the function.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.