What's wrong with this code?

https://play.golang.org/p/lVgxVaeL8Jp

The compiler tells you exactly what is wrong. Which of those 3 messages do you not understand?

None of them!!!

  1. missing condition in if statement:

You have an extra semicolon in if x == 2;. If you only want a condition (instead of assignment and test), there’s no semicolon needed before the opening bracket.

  1. unexpected !, expecting semicolon or newline

if x !false is not how you check for inequality. Instead, you need to do if x != false.

  1. unexpected newline, expecting comma or )

You are just missing the closing parenthesis at fmt.Println("neither".

Once you fix all the issues you’re still going to have the problem of x (an integer) being compared to false. Which is not a legal evaluation. mismatched types int and bool.

This is extremely helpful. I attempted to correct my errors and got this:
https://play.golang.org/p/UwJWHt17sYV

This is interesting. I had not come across the information you gave and was experimenting.

As Hatnice said, you have mismatched types in your comparisons.

Also and just to clarify a little about the first error you got earlier, a semicolon is allowed in an if to do things like this:

func main() {
    if i, err := strconv.Atoi("42"); err == nil {
		fmt.Printf("%d\n", i+1) //Will print 43
	} else {
		fmt.Println(err)
	}
	
	if i, err := strconv.Atoi("42dwcdc"); err == nil {
		fmt.Printf("%d\n", i+1)
	} else {
		fmt.Println(err) //Will print an error
	}
}

When you are just testing a condition, as was x == 2, a semicolon is a syntax error.

Please note that in this case i and err are local to the if-else scopes, not to the main function. That’s why it’s possible to declare them more than once, and why if you try to use them later in main you’ll get an error, e.g. undefined: i if you try something like fmt.Println(i).

Check If at the tour (see this and the next 2 slides): https://tour.golang.org/flowcontrol/5

About the mismatched types…

The line x := 2 declares x and sets it to 2, which is an integer. So x is an int type variable. The statement is equivalent to

var x int = 2

But then you try to compare it to false, which is bool. In Go, you cannot set an integer to true or false, and you can’t set a bool variable to an integer, like 2 or 73452. And you can’t compare them using ==, !=, etc. either because true and false have no integer equivalent. (Even though you might like to think of them as being like 1 and 0.)

(You could get away with this in other languages, like C, where a non-zero integer is considered “true”. But Go doesn’t allow that.)

There are times when you might want to compare values of different types, or set a variable of one type to a value that is another type. For that, it’s possible to convert one type to another.

For example,

var int_number int = 73
var float_number float32

float_number = float32(int_number)

sets float_number to 73.0. (Just writing float_number = int_number will result in an error.) To do a conversion, use a data type as if it’s a function, with the variable you want converted as its argument.

But in the case you showed, it doesn’t make sense to convert a bool to an int, so int(x) won’t work.

I hope that helps you understand this stuff better.

2 Likes

I am having trouble understanding your information.

I understand a little of what you say but not all. I understand I am not allowed to do what I did but not everything else . (by the way I don’t understand what I did either :joy: . I was just playing around)

Can you let me know where you are starting to have difficulty? I can explain things better.

Hi, what is it that’s confusing?

Okay, I will take one thing at a time. What"s the definition of “declares” here?

I think I am like a baby learning to speak. All the language is coming at me but I don’t understand it. I have no background in programmin.
So, first, what does this mean? err := strconv.Atoi(“42”); err == nil

You can think of yourself talking to the Go compiler. It is just a machine and you need to be very specific about everything, and speak exactly its language.

Go is a language that requires every variable to have a specific type. Since the compiler needs to know which type you want a variable to be, naturally, you need to tell it. You do that by declaring the variable. Here is a simple example, similar to what you’ve already seen and used:

var abc int

This declaration tells the compiler that you are using a variable named abc and that it is an integer (actually, an int), rather than some other type (like a string, floating-point number, slice, rune, and so on). Now that the Go compiler knows that, if you make a mistake and try to set abc to another kind of type, or use it as something other than an integer, it will tell you that you have made an error.

I’m thinking that this must seem very complicated to anyone who is just starting as a programmer. Maybe you are asking, “Why is it made so complicated and difficult?” The answer to that is that you have to consider what it’s like to have a program in an untyped language that is thousands (or even hundreds of thousands) of lines long, and then get an error that seems to be telling you that 2 + 3 is “not a number”! Then you have to analyze your (or someone else’s) code to see where a variable was used as an integer when it actually contained a string or something else instead of an integer. In large programs, that’s hard and not fun! Instead of quietly allowing you to dig your own grave, Go’s compiler catches type mismatches during compilation. Then you can fix the problem quickly and easily, and continue creating your program, which is a lot easier, and a lot more fun. I hope that helps.

Years ago I tried learning a little Japanese, and the first part was to learn to write the hiragana alphabet. I had the same feeling! I had to practice writing every character over and over. I felt like I was 5 years old and just learning to write.

Fortunately, any programming language is a lot easier to learn than Japanese. So don’t worry.

About the code snippet, you didn’t get the whole thing. Try this:

if i, err := strconv.Atoi("42"); err == nil { /* statements */ }

This is an example of a more complicated if/then construct. It is equivalent to

i, err := strconv.Atoi("42")
if err == nil { /* statements */ }

Go allows you to insert a statement before the boolean expression of the if statement. It’s just to allow for more concise code. (Personally, I think it’s best to avoid using it, except for very simple cases.)

The first line is like this:

x, y = 1, 2

which sets x to 1 and y to 2. It’s called a tuple assignment. It’s nearly the same as

x = 1
y = 2

But when you have a function that returns multiple values, you have to use a tuple assignment to store those values in variables. So

i, err := strconv.Atoi("42")

results in the string "42" being converted into an int and stored in i, and err will be something other than nil if Atoi() ran into a problem. It’s a good programming practice to always (or at least usually) check for errors and handle them.

Is that what you needed as an explanation?

1 Like

This is very helpful, and I saved it to a file

Where should I try if i, err := strconv.Atoi(“42”); err == nil { /* statements */ }
I interpreted it as…https://play.golang.org/p/ClDeIx4_LXA

And thanks for the encoragement. The fact that I am a baby when it comes to learning the Go language does not frustrate me , but is instead exciting and fun! Better than watching a football game on tv!

Just to clarify, those are not entirely equivalent. As I stated in my earlier post, when declaring and assigning in the if statement, variables are local to the if scope, not the surrounding function. So, in the first case it’s wrong to try to use the variables after the if (or if - else if - else) scope, i.e.:

func someFunc() {
  if i, err := strconv.Atoi("42"); err == nil { 
    /* 
     Some statements should go here.
     i and err may be used here.
   */ 
  } else {
   // Here i and err are fine too, this is still the if scope.
  }
  fmt.Println(err) //Wrong, err has not been declared in this scope, this won't compile.
}

On the second case, variables will be local to the function scope, so this is fine:

func someFunc() {
  i, err := strconv.Atoi("42")
  if err == nil { /* statements */ }
  fmt.Println(err) //This is fine, err is well defined here.
}

This is explained at the Go tour, on the section I linked before.

1 Like