GopherCon 2016: Francesc Campoy - Understanding nil

By: Gopher Academy

174   5   10321

Uploaded on 08/18/2016

Comments (4):

By anonymous    2017-09-20

In Go interface types are represented by a structure with 2 fields: one denotes its actual type and the other is a pointer to the value.

It means that an interface value is never equal to nil unless the value you passed is actually a nil value.

Relevant and good talk: GopherCon 2016: Francesc Campoy - Understanding nil

Original Thread

By anonymous    2017-09-20

I agree with @milo-chirstiansen that it isn't possible for an anonymous func to refer to its instance in its declaration.

If you're trying to get a feel for writing idiomatic Go code, it might look a bit more like this, doing away with the anonymous func:

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
    Walker(t, ch)
    close(ch)
}

// Walker does the things, made to be called recursively
func Walker(t *tree.Tree, ch chan int) {
    if t.Left != nil {
        Walker(t.Left, ch)
    }
    ch <- t.Value
    if t.Right != nil {
        Walker(t.Right, ch)
    }
}

You might find this interesting...

Go allows some interesting things that aren't possible in other languages. This sometimes requires thinking a little differently about your code.

Frances Campoy gave a talk at GopherCon 2016 about his storied history with the concept of nil in Go. One of his examples of how nil can be used beautifully and idiomatically, involved a solution to receiving the sum for a binary tree. Below is a link starting with this piece of his talk and I'd recommend checking it out if you have the time. ref: https://youtu.be/ynoY2xz-F8s?t=16m28s

I realize you don't have control over the Tree struct in your example, but if you did, here's how your code might look: https://play.golang.com/p/iM10NQXfgw

package main

import "fmt"

// A Tree is a binary tree with integer values.
type Tree struct {
    Left  *Tree
    Value int
    Right *Tree
}

// Walk loads value into channel; caller is responsible for providing and closing chan
func (t *Tree) Walk(ch chan int) {

    // Super interesting: Go supports the calling of a func on a nil instance of a struct
    if t == nil {
        return // return nothing
    }

    t.Left.Walk(ch)  // recursively call Walk on left node
    ch <- t.Value
    t.Right.Walk(ch) // recursively call Walk on right node
}

func main() {
    // Initial value for our tree; I'm not being very idiomatic with this
    tree := &Tree{
        Left:  &Tree{Value: 2},
        Value: 1,
        Right: &Tree{Left: &Tree{Value: 4}, Value: 3},
    }

    ch := make(chan int)

    // Load values into chan in separate goroutine
    // to prevent blocking
    go func() {
        tree.Walk(ch)
        close(ch)
    }()

    // Write each val added to chan until all values
    // have been written and chan is closed
    for val := range ch {
        fmt.Println(val)
    }
}

1

2

3

4

Original Thread

Popular Videos 347

Mathematics of Computer Graphics and Virtual Environments

Submit Your Video

If you have some great dev videos to share, please fill out this form.