A couple questions about https://play.golang.org/p/PdJqR-pSN58

In …v, ok := m[“Barnabas”]
fmt.Println(v)
fmt.Println(ok)
what does ok mean?

Also, what happened here:
if v, ok := m[“Barnabas”]; ok {
fmt.Println(v)

Hi
ok is a variable. In Go a function can return any number of values.
In the if you return two values and then check if ok es true. Go alllows variable creation and checking its value in a inline if…

For the first one, from the Go Tour (here’s the relevant section):

elem, ok = m[key]

If  `key`  is in  `m` ,  `ok`  is  `true` . If not,  `ok`  is  `false` .
If  `key`  is not in the map, then  `elem`  is the zero value for the map's element type.

So, in short, ok (or whatever you call the second value returned when accessing a map, which is a bool) tells you if the key is present or not.

In the second case, in Go if may start with a short statement before the condition check. This is almost equivalent to doing this:

v, ok := m[“Barnabas”]
if ok {
  fmt.Println(v)
}

I say almost because in the latter case ok is local to the function scope in which it is located, while in your case (when the statement is part of the if) ok is local to the if scope, i.e., it can’t be used after the if. Please refer to a previous post where I referred to this. Again, the Go Tour mentions this: https://tour.golang.org/flowcontrol/6

1 Like

Hi Cherolyn,

Please remember to include your link to the Go Playground in your post so we can click on it and see the code. Like this:

In your example, m is a map. It allows you to store elements that correspond to keys. I’ll continue with the assumption that you have a basic understanding of how maps work. Let us know if you need more explanation about maps.

In an array or slice, if you try to use an index of something that is beyond the slice’s or array’s length, you will get a runtime error. That is, if an array a has five elements, an attempt to access array[7] causes a runtime panic. (Because you can’t do that.)

Maps work differently. If you attempt to look up something that isn’t in the map, you will get a zero value. (Which might be 0 for a map of ints, or an empty string ("") for a map of strings. Just to give two of many possibilities.) But it’s also possible to store zero values in maps, so how do you tell if that zero value you retrieved from the map means nothing is stored for that key, rather than it being a zero value that you put there deliberately?

The way that’s handled in Go is that accessing maps provide two values. The first one is the element (either what was stored there previously, or a zero value because there wasn’t anything stored there), along with another value to indicate which of those two cases it is.

The second value (ok in your code) is a bool type, and if it’s true, it means the first value is an element that was stored in the map. If it is false, then it indicates that the first value is a zero value that is the result of looking up something that doesn’t exist in the map.

By the way, just to make sure you understand this,

a, b = 1, 2

is called a tuple assignment. It allows you to set many variables in one line of code. In the above example, a is set to 1, and b is set to 2.

For your second question, that is an example of an if statement with a statement that is before the conditional part. It’s making an access to the map, and putting the 2nd (bool) value in ok. Look at ok after the semicolon. That’s what determines whether the fmt.Printf() statement is executed. It is basically saying:

If the map has an element that corresponds to "Barnabas", then print the element.

3 Likes

No, it’s not, it is called a multi value assignment.

If go had tuples, I could do t := 1, 2 and pass t around as if it would contain both values.

Tuples are structs where the fields don’t have names but are identified by their index/position.

2 Likes

Hi Norbert,

I’m using terminology directly from The Go Programming Language Specification. The term tuple assignment is explained in the section on Assignments:

See the part after the third light-grayed box. I’ll put it here to save you time:

A tuple assignment assigns the individual elements of a multi-valued operation to a list of variables. There are two forms. In the first, the right hand operand is a single multi-valued expression such as a function call, a channel or map operation, or a type assertion. The number of operands on the left hand side must match the number of values. For instance, if f is a function returning two values,

x, y = f()

assigns the first value to x and the second to y . In the second form, the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the n th expression on the right is assigned to the n th operand on the left:

one, two, three = ‘一’, ‘二’, ‘三’

2 Likes

Then the go spec disagrees with common terminology in the computer science world.

So is ok just a random variable that the teacher chose or does it refer to something specific in Go?

Yes. It is a chosen name. Not a reserved word.

Not really. Go has Tuple assignment, just no Tuple type. But that’s a bit off topic so I won’t go too in depth.

1 Like
if v, ok := m["Barnabas"]; ok {
  // declare two new variables: v and ok
  // if ok variable is true; then the code here will be executed
  // so, it will print the v variable
  fmt.Println(v)
}

This is called the “comma ok idiom”. “ok” is not a reserved word, however, it’s vastly used in Go.

For example, when checking whether a map value contains the said key or not (as in your example).

Getting a vague understanding of this

What does zero value mean? I know it has something to do with bool but I don’t have a handle on it

This is pretty clear to me.

Thanks for this

Thanks

Oh, ok. This is pretty clear

Yes. It is a chosen name. Not a reserved word.
Chosen by the person writing the program? (See how elemental is my understanding?)

But that’s a bit off topic so I won’t go too in depth

Thanks :slight_smile:

if v, ok := m["Barnabas"]; ok {
  // declare two new variables: v and ok
  // if ok variable is true; then the code here will be executed
  // so, it will print the v variable
  fmt.Println(v)
}

Very helpful