Chris Padilla/Blog

My passion project! Posts spanning music, art, software, books, and more
You can follow by RSS! (What's RSS?) Full archive here.

    Brunner - Rondoletto

    Listen on Youtube

    Biiiiig finger twister! 🔀


    WHO has the smoothest moves?

    Hootin' and scootin'


    Structs in Go

    There are two ways of creating datatypes similar to JavaScript Objects and Python Dictionaries in Go: Structs and Maps.

    Structs are a collection of data that are related. Values are stored next to each other in memory. Structs are also a value type.

    Maps are a hash map data type. They are a key value pair where both keys and values are statically typed individually. So all keys need to be of the same type, and all values need to be the same type. The main benefit is that, as a hash map, indexing and look up is much faster.

    Let's break all that down:

    Values are stored next to each other assuming the value will be lightweight. In this way, it's similar to an array where the keys are strings. Though, the values are not indexed the way that a hash map would for its keys. The tradeoff is that the value is lighter on memory, but slower to iterate through.

    Structs are a value type. So if we were to pass them into a function, the entire struct would be copied. Maps, on the other hand, are a reference type. The address in memory for the Map is passed into a function and any changes to the map within the function will occur as a side effect to the same Map.

    Structs

    Declaring structs requires a type to be created first:

    type car struct {
        make        string
        model        string
        maxSpeed    int
    }
    
    c := car{make: "Toyota", model: "Prius", maxSpeed: 120}

    Methods

    Go isn't an Object Oriented Language, but like JavaScript, can be implemented with similar principles. An example is having methods on Structs:

    type car struct {
        make        string
        model        string
        maxSpeed    int
    }
    
    func (c car) floorIt() int {
        return c.maxSpeed
    }
    
    c := car{make: "Toyota", model: "Prius", maxSpeed: 120}
    c.floorIt() // 120

    Embedding

    Another OOP principle borrowed in Go is composition. In Go, we can embed structs to create more complex types while still maintaining the flexibility of smaller pieces available as individual structs.

    type car struct {
        make        string
        model        string
        maxSpeed    int
    }
    
    type raceCar struct {
        car
        turboEngine    string
    }
    
    rc := raceCar{
        car: car{
            make: "Toyota",
            model: "Prius",
            maxSpeed: 120,
        },
        turboEngine: "MAX"
    }

    Go Performance

    Performance and Memory

    When looking at a language's performance, the two considerations here are memory usage and performance speed.

    Taking two ends of the spectrum, we could look at Rust on one end and C# on the other.

    C# is a high level language that requires interpreting through a Virtual Machine. (A strange example, perhaps, because C# does compile, but only to the Intermediary Language, and not directly to machine code) C# Also handles memory management. The overhead of the virtual machine and memory management leads to a fluid developer experience, but makes compromises in performance speed and memory usage.

    Rust, on the other hand, is a compiled language. Meaning that to run rust, you'll build an executable from the human readable Rust code. This saves the time it would take a virtual machine to interpret the language. Or, in the case of Python or Ruby, it would eliminate the time it takes for the runtime to interpret the script.

    Rust also requires the developer to do much of their own memory management. When written properly, this allows for really performant applications, since that's an extra bit of overhead taken off from running Rust code.

    Where Go Fits

    Go uniquely sits an a great position between these two ends to balance the benefits offered by a higher level language while still providing the speed of a compiled language.

    Go does compile to machine code. You can run go build main.go to compile the script down to an exe file. So we get the benefit of quick execution, eliminating the need for interpretation time.

    While doing so, Go bundles a much lighter package called the Go Runtime that handles Garbage Collection. With a specialized focus on memory management, this still allows for that DX experience while not adding as much overhead as the Java Runtime Environment or the Common Language Runtime in C#.

    Comparisons of Go's speed are right between the end of compiled, non-Garbage Collected languages like C, C++, and Rust, and the higher level language features of Java and C#.

    One added benefit of being compiled is having one less dependency in your deployment environment. The platform isn't required to have a specific version of a Go interpreter available to execute a program.


    Parkening - A Minor Study

    Listen on Youtube

    Lucy can tell when I'm about to finish recording, she knows rubs are soon to follow!