Skip to content

Instantly share code, notes, and snippets.

@tyndyll
Last active February 26, 2019 12:44
Show Gist options
  • Save tyndyll/cce72c16dc112cbe7ffac44dbb1dc5e8 to your computer and use it in GitHub Desktop.
Save tyndyll/cce72c16dc112cbe7ffac44dbb1dc5e8 to your computer and use it in GitHub Desktop.

Revisions

  1. tyndyll revised this gist Feb 26, 2019. No changes.
  2. tyndyll revised this gist Jan 15, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@ The talk was a very high level introduction to go, and the code here is a commen
    ## Running
    It is assumed that you have previously [downloaded and installed Go](https://golang.org/dl/), and [configured it appropriately](https://golang.org/doc/install#testing)

    Clone this gist or simply download the `hello_world.go` file. We are not importing any external packages so it doesn't necessaryily have to exist inside the GOPATH.
    Clone this gist or simply download the `hello_world.go` file. We are not importing any external packages so it doesn't necessarily have to exist inside the GOPATH.

    ```
    go run hello_world.go
  3. tyndyll revised this gist Jan 15, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ This gist is the code portion of a talk given at the [Crystal Ball Bash](https:/
    The talk was a very high level introduction to go, and the code here is a commented example of the syntax and features that Go has to offer. It is a Hello World example, but with the twist of being a HTTP server, that uses concurrency to print out to the terminal. It looks long, but it amounts to about 50 lines of actual code once you remove the comments

    ## Running
    It is assumed that you have previously [downloaded and installed Go](https://golang.org/dl/), and configured [configured it appropriately](https://golang.org/doc/install#testing)
    It is assumed that you have previously [downloaded and installed Go](https://golang.org/dl/), and [configured it appropriately](https://golang.org/doc/install#testing)

    Clone this gist or simply download the `hello_world.go` file. We are not importing any external packages so it doesn't necessaryily have to exist inside the GOPATH.

  4. tyndyll revised this gist Jan 15, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    # Hello World
    This gist is the code portion of a talk given at the [Crystal Ball Bash](https://www.meetup.com/devbash/events/257129240/).

    The talk was a very high level introduction to go, and the code here is a commented example of the syntax and features that Go has to offer.
    The talk was a very high level introduction to go, and the code here is a commented example of the syntax and features that Go has to offer. It is a Hello World example, but with the twist of being a HTTP server, that uses concurrency to print out to the terminal. It looks long, but it amounts to about 50 lines of actual code once you remove the comments

    ## Running
    It is assumed that you have previously [downloaded and installed Go](https://golang.org/dl/), and configured [configured it appropriately](https://golang.org/doc/install#testing)
  5. tyndyll revised this gist Jan 15, 2019. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -40,7 +40,7 @@ GOARCH=arm go install
    Depending on the combination of GOOS and GOARCH, you will find the resulting output in a directory inside $GOPATH/bin

    ## Resources
    [A Tour of Go](https://tour.golang.org/welcome/1)
    [Go Docs](https://golang.org/doc/)
    [Go Playground](http://play.golang.org)
    * [A Tour of Go](https://tour.golang.org/welcome/1)
    * [Go Docs](https://golang.org/doc/)
    * [Go Playground](http://play.golang.org)

  6. tyndyll revised this gist Jan 15, 2019. 1 changed file with 43 additions and 1 deletion.
    44 changes: 43 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,46 @@
    # Hello World
    This gist is the code portion of a talk given at the [Crystal Ball Bash](https://www.meetup.com/devbash/events/257129240/).

    The talk was a very high level introduction to go, and the code here is an example of the syntax and features that Go has to offer
    The talk was a very high level introduction to go, and the code here is a commented example of the syntax and features that Go has to offer.

    ## Running
    It is assumed that you have previously [downloaded and installed Go](https://golang.org/dl/), and configured [configured it appropriately](https://golang.org/doc/install#testing)

    Clone this gist or simply download the `hello_world.go` file. We are not importing any external packages so it doesn't necessaryily have to exist inside the GOPATH.

    ```
    go run hello_world.go
    ```

    You can then open a browser and go to http://localhost:8080?name=YourName to get your special hello message. Flicking back to the terminal will show a log entry of the message receive

    ## Compiling
    If you wish to compile the binary to demonstrate the portability of the Go compiler, simply run

    ```
    go install
    ```

    in the directory containing the `hello_world.go` file. To remove ambiguity I would strongly recommend creating a directory first and moving the file into it. If `go install` succeeds, going to $GOPATH/bin will show the compiled file, which will be the name of the directory it was compiled from. To compile for other operating systems, simply set the `GOOS` environmental variable e.g.

    ```
    GOOS=linux go install
    GOOS=windows go install
    GOOS=darwin go install # OSX
    ```

    For different architectures, set the `GOARCH` variable

    ```
    GOARCH=amd64 go install
    GOARCH=386 go install
    GOARCH=arm go install
    ```

    Depending on the combination of GOOS and GOARCH, you will find the resulting output in a directory inside $GOPATH/bin

    ## Resources
    [A Tour of Go](https://tour.golang.org/welcome/1)
    [Go Docs](https://golang.org/doc/)
    [Go Playground](http://play.golang.org)

  7. tyndyll revised this gist Jan 15, 2019. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions hello_world.go
    Original file line number Diff line number Diff line change
    @@ -188,5 +188,4 @@ func main() {
    // GO! This starts the HTTP server on port 8080. There is also a TLS server
    // available that operates in the same manner
    http.ListenAndServe(":8080", nil)
    }
    (paidup) ➜ instil
    }
  8. tyndyll revised this gist Jan 15, 2019. 1 changed file with 192 additions and 1 deletion.
    193 changes: 192 additions & 1 deletion hello_world.go
    Original file line number Diff line number Diff line change
    @@ -1 +1,192 @@
    package main
    // package main is the entry point into the application.
    //
    // Packages are used to bundle common pieces of code together for the purposes
    // of application architecture or for reusablility in other applications. The
    // package name should be the first line of the file after any initial comment
    //
    // These comments in the code are used to generate the documentation which can
    // be made available via the godoc tool. These particular comments will not
    // show as this is the main package however. For further information see
    //
    // https://blog.golang.org/godoc-documenting-go-code
    package main

    import (
    // These three packages are both from the standard library, the
    // documentation for which can be found at
    //
    // https://golang.org/pkg/
    //
    // To import packages, they can be easily pulled from source control
    // via the go get command
    // e.g. go get github.com/tyndyll/alexa
    // which will fetch a package to work with Alexa requests in Go, and
    // which when imported could be accessed via alexa.FunctionName().
    // Imports can also be aliased in the case where there are packages
    // with the same name
    "fmt"
    "log"
    "net/http"
    )

    // Printer defines the print interface
    //
    // Interfaces in Go contain a list of functions that a type must implement
    // in order to satisfy it. Any type that satisfies an interface can be
    // passed to a function that takes the interface as a parameter.
    type Printer interface {
    // Print outputs the provided string. There are no return values
    Print(string)
    }

    // linePrinter is the first type we will use to implement the Print interface
    // It is a simple printer that will simply output the passed string to a log
    //
    // Note that the linePrinter type starts with a lower case 'l'. In Go types and
    // functions that start with a lower case letter are private, while types and
    // functions that start with an upper case letter are Public, and available
    // outside of the package (and in the documentation)
    type linePrinter struct{}

    // Print takes a string and does not return anything. The Print function is
    // defined onto a pointer to the linePrinter type. 'p' is roughly equivalent to
    // self, but is rarely if ever called that. For more information see
    // https://golang.org/doc/effective_go.html#methods
    func (p *linePrinter) Print(name string) {
    log.Printf(p.BuildString(name))
    }

    // BuildString takes a name, and returns a combined string. This isn't in the
    // original Printer interface, but that doesn't matter. The check as to whether
    // it conforms to the interface is just the list of methods that the interface
    // defines
    func (p *linePrinter) BuildString(name string) string {
    return fmt.Sprintf("Hello %s\n", name)
    }

    // GreeterService is the type that will contain a function that will provide
    // the HTTP handler. We could just use a function, but we want to have access
    // to a variable without relying on a global
    type GreeterService struct {
    // ToPrinter is a field on the struct, which contains a channel through
    // which strings can be passed. Fields are accessed via a dot notation
    // If no value is assigned to it, it will automatically be given a
    // nil value
    ToPrinter chan string
    }

    // SayHello is a function which implements the HTTP Handler interface.
    // https://golang.org/pkg/net/http/#Handler
    // The ResponseWriter is an instance of type, while the request is a pointer
    // to it
    func (g *GreeterService) SayHello(w http.ResponseWriter, r *http.Request) {
    // name is using the short declaration form to create a new variable. It
    // tells the compiler, take the type of the value that is returned from
    // the right hand side, and create a variable called name with that type
    //
    // We can see that we are accessing the URL field of the request. From
    // that URL we are calling the Query function to get a Values type, and
    // then the Get method. This only works up to the Get call if the function
    // has a single return
    name := r.URL.Query().Get("name")
    // There are no brackets around the if statement, and the { is required
    // on this line to terminate the statement
    if name == "" {
    // I'm sorry, I watch a lot of CSI while I'm working
    http.Error(w, "Who are you? (who who, who who)", http.StatusBadRequest)
    return
    }

    // We have a name, so we want to pass that through to the printer to let
    // it do what ever it is that it does. This type has no idea what that
    // could be and doesn't really care. The only time this would be a concern
    // is if the channel becomes full, at which point this call will block
    g.ToPrinter <- name

    // This type of if statement is very common in Go, where the if statement
    // is tested, and then a check performed after the semi colon. These can
    // be chained with && and ||
    //
    // The _ variable throws away the value that is assigned to it (in this case
    // the number of bytes written). Go refuses to compile if there are variables
    // that are declared and not used, so it is necessary to throw them away or
    // delete them
    if _, err := w.Write([]byte("Hello " + name)); err != nil {
    http.Error(w, "Server Write Error", http.StatusInternalServerError)
    return
    }
    // The function automatically returns
    }

    // main is the entry point to the program. It takes no arguments and does not
    // return anything. Any command line arguments are available via the os.Args
    // variable (which requires importing the os package)
    func main() {
    // We are creating a channel that will contain strings, giving it a
    // buffer size of 10. The make keyword properly creates the structure
    // and sizes it appropriately
    //
    // Channels are a convenient way to pass information through goroutines
    // without having to rely on locks and mutexes.
    // https://golang.org/doc/effective_go.html#channels
    printerChannel := make(chan string, 10)

    // Create an instance of the linePrinter type. We are creating a
    // pointer to the struct by asking for it's address (&).
    printer := &linePrinter{}

    // We are creating an anonymous function and then running it in a
    // goroutine (https://golang.org/doc/effective_go.html#goroutines)
    //
    // The function accepts an argument which satisfies the Printer
    // interface

    // At this point this function will be executed in the background
    // and the program will continue
    go func(p Printer) {
    // This is the long form declaration. It is possible to assign
    // a value here (e.g. var name string = "Tyndyll") but in this
    // instance name will be set to ""
    var name string
    // We want this loop to run forever
    for {
    // Using the channel defined above, we use the <-
    // notation to take a value from the channel, if one
    // is available. If the channel is empty this request
    // will block.
    name = <-printerChannel

    // Call the Print method. Attempts to call the other
    // Public method BuildString would fail, because we have
    // explicitely passed through and typed it as the
    // Printer interface, which only has the Print method.
    // To access the other methods we could cast this to the
    // appropriate type.
    //
    // What is important to realise here, is that we could
    // have a type, which prints the result to an actual
    // printer, or emails it, or displays it on a stadium
    // jumbotron. We don't care what the type is, as long
    // as it satisfies the interface
    p.Print(name)
    }
    }(printer)
    // The goroutine is now being started

    // Create an instance of a pointer to a GreeterService
    g := &GreeterService{
    // Set the initial value of the field. Notice the comma at the
    // end of the line. This is another of Go's style idioms, which
    // declares that you're always going to add another field
    // eventually, lets add the comma and avoid the error later
    ToPrinter: printerChannel,
    }

    // For the route "/", take use the function pointed to here.
    http.HandleFunc("/", g.SayHello)

    // GO! This starts the HTTP server on port 8080. There is also a TLS server
    // available that operates in the same manner
    http.ListenAndServe(":8080", nil)
    }
    (paidup) ➜ instil
  9. tyndyll created this gist Jan 15, 2019.
    4 changes: 4 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    # Hello World
    This gist is the code portion of a talk given at the [Crystal Ball Bash](https://www.meetup.com/devbash/events/257129240/).

    The talk was a very high level introduction to go, and the code here is an example of the syntax and features that Go has to offer
    1 change: 1 addition & 0 deletions hello_world.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    package main