Moving from NodeJS to Go

Moving from NodeJS to Go

You are a seasoned NodeJS developer, and are looking to learn a new language, but you don't want to go deep, just see how things compare with your current expertise, and then make a final decision.

You are a seasoned NodeJS developer, and are looking to learn a new language, but you don't want to go deep, just see how things compare with your current expertise, and then make a final decision.

The approach of this article is this:

Table of Contents

  • Why Go
  • Hello World
  • Data Types, Variables and Constants
  • Conditional Statements
  • Loops
  • Objects
  • Http Server
  • Middleware
  • Consuming APIs
  • Database Connections
  • Frameworks
  • Conclusion

You are a seasoned NodeJS developer, and are looking to learn a new language, but you don’t want to go deep, just see how things compare with your current expertise, and then make a final decision.

Chances are, you were initially a PHP or Python developer, then you found your way into NodeJS and now you feel like you want to expand your expertise. Of course I might be wrong, but in this article we are going to look at some common patterns when working with NodeJS and how they compare in Go.

Why Go

The most common reasons to learn Go include the following:

  • Why Go
  • Hello World
  • Data Types, Variables and Constants
  • Conditional Statements
  • Loops
  • Objects
  • Http Server
  • Middleware
  • Consuming APIs
  • Database Connections
  • Frameworks
  • Conclusion

Here’s an example with the net/http package in the go documentation. Examples are provided, and there are even tabs for the source code files. Sweet!

Is Go Better Than **JavaScript **?. No, I don’t think so, nor do I think JavaScript is better. The idea is to use the right tool for the job, and sometimes, one tool is better than another one, or one developer is better in one tool over another. So learn what you can, and choose the right thing that you are sure will get the job done for you.

Hello World

Here’s a hello world program in NodeJS

console.log('Hello World');

Running this will produce Hello World in the terminal.

node app.js

Here’s an equivalent hello world program in Go

package main

import "fmt"

func main() {
    fmt.Println("Hello World")
}

Go follows a certain structure which involves:

  • Why Go
  • Hello World
  • Data Types, Variables and Constants
  • Conditional Statements
  • Loops
  • Objects
  • Http Server
  • Middleware
  • Consuming APIs
  • Database Connections
  • Frameworks
  • Conclusion

This code can be run by typing in the following, or see it in GoPlay Space.

go run main.go

where main.go is the name of the file.

Data Types, Variables and Constants

JavaScript is dynamically typed, which means you do not have to specify types when defining variables, and the variables can change their types as you program along.

That being said, JavaScript has the following types:

To define variables in JavaScript(NodeJS) we’d write this:

const num = 3; // declaring a constant number
let flt = 2.34; // declaring a number (float)
let a = true; // declaring a boolean
let b = false;
var name = 'Scotch'; // declaring a string 

Go however, is statically typed, which means we have to define the types before hand, or assign them and let them be inferred. Here’s a comprehensive list of Go Types.

An equivalent of the above JavaScript definitions in Go is

package main

const num = 3 // declaring a constant

func main() {
    var flt float64 = 2.34 // declaring a float 
    var name string = "Scotch" // declaring a string
    a, b := true, false,  // shorthand declaration syntax
}

Assigning initial values in Go is done by with the var keyword, a variable name, and a type. Additionally and more commonly the := shorthand syntax can be used. When declaring variables with := , they are automatically assigned the correct type. Additionally, you can assign multiple values in one line like we have done in a, b := true, false. This will assign both a and b to the right hand values respectively.

Here is an array of strings in JavaScript

const names = ['Scotch', 'IO'];

While Go has arrays, what we typically refer to arrays in JavaScript are referred to as slices in Go. Here’s an example of a slice in Go:

package main

func main() {
    names := []string{"Scotch", "IO"}
}

As an example, we’ll write a small program that returns the substring of a string at index 10. So a sentence like Luke, I'm not your father will end up being Luke, I'm

JavaScript

const sentence = '`Luke, I\'m not your Father';`
console.log(sentence.substr(0,10));

Go

package main

import "fmt"

func main() {
    sentence := "Luke, I'm not your Father"
    fmt.Println(sentence[:10])
}

You can run the app in Goplay Space

Conditional Statements

Conditional statements include if else and switch statements. Here’s an example in NodeJS.

const age = 10;

if (age > 10) {
    console.log('you are old');
} else {
    console.log('you are young');
}

const gender = 'female';

switch (gender) {
    case 'female':
        console.log('your name is tonie');
        break;
    case 'male':
        console.log('your name is tony');
        break;;
    default:
        ///
}

Here’s an equivalent in Go

package main

import "fmt"

func main() {
    age := 10
    if age > 10 {
        fmt.Println("you are old")
    } else {
        fmt.Println("you are young")
    }

    gender := "female"
    switch gender {
    case "female":
        fmt.Println("your name is tonie ")
    case "male":
        fmt.Println("your name is tony")
    default:
        ///
    }
}

You can run the app in GoPlay Space.

You’ll notice the conditionals are a bit cleaner in Golang, with less brackets.

Loops

JavaScript has 3 loops: for loop, while loop, and a do while loop. Here’s a for loop example.

// normal for loop
for i = 0; i < 10; i++ {
    console.log(i);
}

// key, value loop
for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + ' -> ' + p[key]);
    }
}

// another key value loop
Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
})

// there's also a `for...of`

Go has only one type of loop, and it’s the for loop. Don’t let that deceive you though as the for loop in Go is very versatile and can emulate almost any type of loop. Let’s look at a simple example:

package main

import (
    "fmt"
)

func main() {
    for i := 0; i < 10; i++ {
        fmt.Println(i)
    }

    // key value pairs
    kvs := map[string]string{
        "name":    "Scotch",
        "website": "https://scotch.io",
    }

    for key, value := range kvs {
        fmt.Println(key, value)
    }
}

You can run the app in GoPlay Space.

Objects

Objects are a big part of JavaScript and exist in almost every program. Here’s an Object in JavaScript.

// an object
const Post = {
    ID: 300
    Title: "Moving from NodeJS to Go",
    Author: "Christopher Ganga",
    Difficulty: "Beginner",
}

console.log(Post)

// access values
console.log(Post.ID)
console.log(Post.Title)
console.log(Post.Author)
// ....

// we can also define classes in javascript.

Since Go is statically typed, we need to do a little extra to define objects. There are two ways to do this, and it involves using map. A map is a key value data structure, where the keys are a set (does not contain duplicates).

package main

import (
    "fmt"
)

func main() {
    Post := map[string]interface{}{
        "ID":         300,
        "Title":      "Moving from NodeJS to Go",
        "Author":     "Christopher Ganga",
        "Difficulty": "Beginner",
    }

    fmt.Println(Post)

    // to access values
    fmt.Println(Post["ID"])
    fmt.Println(Post["Title"])
    fmt.Println(Post["Author"])
    // ....
}


You can run this example in Goplay Space

The other way to write obects in Go is by using Structs. A struct is an abstract data structure, with properties and methods. It’s a close equivalent to a Class in Javascript.

package main

import (
    "fmt"
)

type Post struct {
    ID         int
    Title      string
    Author     string
    Difficulty string
}

func main() {
    // create an instance of the Post
    p := Post{
        ID:         300,
        Title:      "Moving from NodeJS to Go",
        Author:     "Christopher Ganga",
        Difficulty: "Beginner",
    }

    fmt.Println(p)

    // to access values
    fmt.Println(p.ID)
    fmt.Println(p.Title)
    fmt.Println(p.Author)
    // ....
}

Struct defines the name of the type and its properties together with the types. We can then create an instance of the type (Post).

You can run this in Goplay Space

Http Server

Now that we know a little about the similarities and differences in language constructs, we can have a look at servers. Since we are coming from NodeJS it’s likely that we’re building a server, that returns JSON for instance.

In NodeJS, chances are while writing a server, you are using Express as the base library for your server. It’s the most common, comes with a router and is the most battle tested. Here’s a NodeJS server.

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello from Express!');
})

app.listen(3000, err => {
  if (err) {
    return console.log('something bad happened', err);
  }

  console.log('`server is listening on 3000'`);
})

The Go standard library provides everything we need to get a server up and running without any external dependencies. The net/http package provides most of this functionality. When building larger applications however, expanding on the base net/http package with third-party packages is common, and one popular package that provides greatly a lot of functionality is the Gorilla Web Toolkit.

Here’s an equivalent Server in Go .

package main

import (
    "net/http"
)

func Hello(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello World"))
}

func main() {
    http.HandleFunc("/", Hello)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

We call http.HandleFunc and give it a route and a handler. Almost sililar to the callback we give to express routes.

You can test this by running go run main.go, assuming your file was named main.go

Now, let’s introduce a router library, because, if we don’t, we’ll have to test whether a request came as a POST , GET or the likes, and use if statements to match specific routes. Something like this:

if req.Method == "POST" {
    // do this
}

To get packages with golang, you usually use a go get <github-link>. To get Gorilla Mux from the Gorilla Web Toolkit we mentioned earlier, we would write the following in our terminal:

go get -u github.com/gorilla/mux

Then we are able to do this. I pulled this directly from Gorilla mux documentation.

package main

import (
     "fmt"
     "net/http"

     "github.com/gorilla/mux"
)
func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", HomeHandler)
    r.HandleFunc("/products", ProductsHandler)
    r.HandleFunc("/articles", ArticlesHandler)

    // details
    r.HandleFunc("/products/{key}", ProductHandler)
    r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
    r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

    http.Handle("/", r)
}

// example handler
func ArticlesCategoryHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "Category: %v\n", vars["category"])
}

We see that the same way express accepts patterns, Gorilla mux allows us to use the same patterns. It can get a little complicated than what I’ve described, but I hope you get the idea.

Gorilla mux also comes with helper functions that npm’s body parser helps us achieve. Go purist can however claim that these function can easily be written.

Middleware

Middleware are a great part of NodeJS servers.

They are functions that sit somewhere, and are run before or after the actual request is run. In NodeJS, this is a simple snippet for a middleware that retrieves a secret from the env and uses it to authenticate a user. When reading variables from NodeJS, dotenv is commonly used.

const express = require('express');
const app = express();

// add server_name middleware
function authenticate((req, res, next) => {
    const secret = process.ENV.SECRET;
    if (secret == "") {
        return res.send("secret not found");
    }

    if (!isAuthenticated(req, secret)) {
        return res.send("invalid authentication");
    }

    return next();
})

// use middleware
app.get('/', authenticate, (req, res) => {
  res.send('Hello from Express!');
})

app.listen(3000, err => {
  if (err) {
    return console.log('something bad happened', err);
  }

  console.log('`server is listening on 3000'`);
})

Go takes a similar approach. Since all a middleware does is take in a request, do something with it and decide whether the request should proceed.

package main

import (
    "net/http"
    "os"
)

// our sample authenticate middleware
func Authenticate(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r _http.Request) {
        secret := os.Getenv('SECRET')
        if secret == "" {
            w.Write(_[_]byte("secret not found")
            return
        }

        if !isAuthenticated(r, secret) {
            w.Write(_[]byte("invalid authentication"))
            return
        }
        next.ServeHTTP(w, r)
    }
}

func Hello(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello World"))
}

func main() {
    http.HandleFunc("/", Authenticate(Hello)) // call the middeware by wrapping
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

If you are a seasoned JavaScript developer, you’ve probably noticed functions are first class citizens in Go too.

We’ve just written a function that takes in a [http.HandlerFunc](https://golang.org/pkg/net/http/#HandlerFunc "http.HandlerFunc") which is a function type, and the function structure is type HandlerFunc func(ResponseWriter, *Request), just like the Handler we wrote.

The advantage is that the http.HandlerFunc type has a function ServeHTTP which takes in the response and the request pointer we passed, and executes the handle call.

Some people call this approach wrapping functions, but this is the general idea. Again, you can easily write your own middlewares, but there are a couple of libraries out there to help you like

  • Why Go
  • Hello World
  • Data Types, Variables and Constants
  • Conditional Statements
  • Loops
  • Objects
  • Http Server
  • Middleware
  • Consuming APIs
  • Database Connections
  • Frameworks
  • Conclusion
Consuming APIs

Most of the time, our servers usually depend on an external API to get some data it needs. Let’s say for example we are getting users from Github.

This is the approach you would take in a NodeJS app.

You’ll first install a http request module, such as axios. npm install axios

const axios = require('axios');
const url = 'https://api.github.com/users';

axios.get(url).then(res => {
    // do something with the response
}).catch(err => {
    // do something with the error
})

This piece of code can either be in your service, or anywhere you like.

In Go, however, the [net/http](https://golang.org/pkg/net/http/ "net/http") package can help us with this scenario.

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func main() {
    URL := "https://api.github.com/users"
    res, err := http.Get(URL)
    if err != nil {
        log.Println(err)
        return
    }
    defer res.Body.Close() // for garbage collection

    responseBodyBytes, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Println(err)
        return
    }

    fmt.Println(string(responseBodyBytes))
}

We use http.Get to make requests, and check errors. The response is usually in bytes, and we have to read it first, then convert it to string with string([]bytes).

You can add this to a main.go file and run go run main.go.

This code can also easily be converted to a func, and called repeatedly when needed.

Here’e an example showing various ways to use the http package from the net/http documentation page.

resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
    url.Values{"key": {"Value"}, "id": {"123"}})

Database Connections

NodeJS has various npm modules to help in database connections depending on the databases that you are using.

These libraries most of the time come with their own methods, that try to make it easier for you to work with them, and some even offer ORM like features.

Go however takes a different approach. The standard library provides an interface for working with databases called https://golang.org/pkg/database/sql/ which RDBMS package authors can use to implement drivers for various databases. Authors following the standard interface ensure greater interoperability for their packages.

Common database driver packages include:

  • Why Go
  • Hello World
  • Data Types, Variables and Constants
  • Conditional Statements
  • Loops
  • Objects
  • Http Server
  • Middleware
  • Consuming APIs
  • Database Connections
  • Frameworks
  • Conclusion
Frameworks

We all know how JavaScript has a lot of frameworks and libraries, and we use them ocassionally to avoid reinventing the wheel.

The Go community however prefers using libraries instead of frameworks, so you will rarely find a team commiting to a particular framework when building their applications.

That being said, there is one Framework I’d recommend, since it is built by combining a lot of the commonly used packages, and file structures.

  • Why Go
  • Hello World
  • Data Types, Variables and Constants
  • Conditional Statements
  • Loops
  • Objects
  • Http Server
  • Middleware
  • Consuming APIs
  • Database Connections
  • Frameworks
  • Conclusion
Conclusion

Go’s files must be written within packages, and this usually affects your file structure.

In JavaScript, you’ll see a lot of require statements at the beginning of files, while in Golang, the first line is always a package name, which will then be used as an import path in a file where it’s required import package_path/package_name

I hope you’ve gotten a gist of what it’s like to write Go, and you’d like to get into action. Golang is really praised for it’s concurrency and performance, and if you are building a large application, this would be a preferred choice.

I’ve been following this transitional journey for a while now, and would gladly answer any questions you may have. Just leave a comment.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Originally published by Chris Ganga at  scotch.io

Follow us on Facebook | Twitter

Further reading about JavaScript

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

JavaScript Bootcamp - Build Real World Applications

The Web Developer Bootcamp

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

New ES2019 Features Every JavaScript Developer Should Know

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

What JavaScript Framework You Should Learn to Get a Job in 2019?

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

Do we still need JavaScript frameworks?

Google’s Go Essentials For Node.js / JavaScript Developers

Google’s Go Essentials For Node.js / JavaScript Developers

Keep checking this article as I will make it more comparative between Go and Node constructs. This article will be a brain dump of all I’ve learned so far about Google’s Go language.

Keep checking this article as I will make it more comparative between Go and Node constructs. This article will be a brain dump of all I’ve learned so far about Google’s Go language.

As an advanced JavaScript developer, The more I work with JavaScript the more I understand the advantages of a statically typed language.

Paradoxically, it is easier to make TypeErrors in JavaScript than in other languages I have used. When you do work on the back-end, it is unacceptable. On the front end, when you are a little bit serious about your work, you notice how so many JS developer do NOT understand the typing system in JavaScript because it is not forced on them. That’s why there is a lot of garbage JS code in the world.

JavaScript is HARD when you get serious about understanding it under the hood. So many (kind of hidden) complex concepts you have to understand in order to make sense of the errors in your code (or why it’s working but that’s not the correct way to do it…).

JavaScript is fascinating but sometimes you want to try something else and broaden your horizon.

This article will be a brain dump of all I’ve learned so far about Google’s Go language.

I assume you have installed the Go binaries on your computer.

Variables

package main

import "fmt"

func main() {
    // you MUST use a declared variable otherwise compilation error
    
    var toto int8 = 123
    fmt.Println(toto)

    var tito = 123
    fmt.Println(tito)

    // variable declaration with type inference
    toti := 123
    fmt.Println(toti)

    // variable declaration (implicitly initialized to zero-value,// for numeric types = 0)
    var tata int
    fmt.Println(tata)

    // variable assignment
    tata = 951
    fmt.Println(tata)
}

Number Types

package main

import "fmt"

func main() {
    // Go does not convert types automatically
    // need to explicitly convert them
    var (
        i int8    = 20
        f float32 = 5.6
    )
    fmt.Println(i + int8(f+1.9))

    var (
        j int32 = 456
        k int64 = 987654
    )
    fmt.Println(int64(j) + k)

    // byte is an alias for uint8
    // no need to convert uint8 to byte because same
    var (
        l byte  = 123
        m uint8 = 45
    )
    fmt.Println(l + m)

    // int is an alias for int32 or int64, // dedpending on your mqchine's integer value
    var (
        n int32 = 324
        o int   = 84529899
    )
    fmt.Println(int(n) + o)

    // uint is an alias for uint32 or int64
    var (
        p uint   = 999
        q uint64 = 9999
    )
    fmt.Println(p + uint(q))

    // float operations do not produce an exact result after n decimals// like in most languages
    myFloat := 1.000
    myFloat2 := .999
    fmt.Println(myFloat - myFloat2)

    // arithmetic operations
    fmt.Printf("%d + %d = %d \n", 25, 39, 25+39)
    fmt.Printf("%d - %d = %d \n", 25, 39, 25-39)
    fmt.Printf("%d * %d = %d \n", 25, 39, 25*39)
    fmt.Printf("%d / %d = %v \n", 25, 39, 25/39)
    fmt.Printf("%d %% %d = %v \n", 25, 39, 25%39)

    // constants
    const goldenRatio float64 = 1.6180327868852
    fmt.Printf("The golden ration approximately %f \n", goldenRatio)
    fmt.Printf("The ration truncated to the 3rd decimal is %.3f \n", goldenRatio)

    // formatted printing for numeric types
    fmt.Printf("decimal is %d \n", 99)
    fmt.Printf("binary is %b \n", 99)
    fmt.Printf("unicode reference is %c \n", 99)
    fmt.Printf("hexadecimal is %x \n", 99)
    fmt.Printf("scientific notation of goldenRatio is %e \n", goldenRatio)
}

String Types

package main

import "fmt"

func main() {
    // zero-value for strings is an empty string ""
    var str string
    fmt.Println("\"" + str + "\"")

    str = "This is a string."
    fmt.Println(str)

    str2 := "Another string."
    fmt.Println(str2)

    // raw string literalss with back ticks
    // can be written on multiple lines and no escapes
    str3 := `
        Raw string in the building.
        And another line.
    `
    fmt.Println(str3)

    str4 := "Dunya nzuri = "
    str5 := "美麗的世界"
    str6 := str4 + str5
    fmt.Println(str6)

    // In Go, strings are immutable sequences of bytes
    // you can access each byte
    str7 := "mazoezi"
    b1 := str7[0]
    b2 := str7[1]
    fmt.Println(str7, "\n\t", b1, "=", string(b1), b2, "=", string(b2))

    // substrings
    s1 := str7[0:2]
    s2 := str7[2:4]
    s3 := str7[:3]
    s4 := str7[3:]
    fmt.Printf("%s \t %s \t %s \t %s \n", s1, s2, s3, s4)

    // length of string
    fmt.Println(str7, " = ", len(str7), " characters")

    // single character = rune -> numeric type, sane as int32
    // can be converted to a string
    var r rune 
    // single qutoes
    r = '✖'         // same as r = 10006
    fmt.Println("This is a rune : ", r, " which in string = ", string(r))
}

If and For Statements

package main

import "fmt"

func main() {
    a := 27

    // no parentheses surrounding the condition
    // the body of the if statement MUST be surrounded with {} // no matter what
    // no truthy values
    if a > 25 {
        fmt.Println("a is greater than 25")
    } else {
        fmt.Println("a is less than 25")
    }

    b := 546

    // if statement have block scope
    if b == 546 {
        // c does not exist outside of the if
        c := 54
        fmt.Println(b + c)
    }

    // can declare a variable available ONLY in if and else block
    if d := 44; b < 25 {
        fmt.Println("a is greater than 25", d)
    } else {
        fmt.Println("a is less than 25", d)
    }

    // for loop, no parentheses around signature
    e := 2
    for index := 0; index < 10; index++ {
        if index+e == 2 {
            continue
        }
        if index > 8 {
            break
        }
        fmt.Println("index =", index)

    }

    // equivalent of while statement
    f := 0
    for f < 6 {
        fmt.Println("f =", f)
        // don't forget to have smth allowing to get out of the loop
        f++
    }

    // infinite loop
    g := 0
    for {
        fmt.Println("g =", g)
        g++
        // to stop it at some point
        if g > 30 {
            break
        }
    }

    // for range loop
    
    h := "this is great!"
    for k, v := range h {
        fmt.Println("offset (position) =",k,", value as rune =", v, ",value as string = ", string(v))
    }

    // logical operators
    fmt.Printf("%t && %t is %t \n", true, false, true && false)
    fmt.Printf("%t || %t is %t \n", true, false, true || false)
    fmt.Printf("!%t is %t \n", true, !true) 
}

Functions

package main

import "fmt"

func main() {
    addNumbers(353454, 99999)
    addNumbers(353, 9999)
    addNumbers(3554, 99)

    a := addInts(99, 1)
    fmt.Println("a = ", a)

    a = addInts(9, 675)
    fmt.Println("a = ", a)

    div, remainder := divAndRemainder(57, 7)
    fmt.Println(div, remainder)

    // use underscore to ignore a returned value
    div, _ = divAndRemainder(57, 7)
    fmt.Println(div)

    _, remainder = divAndRemainder(57, 7)
    fmt.Println(remainder)

    divAndRemainder(57, 7)

    // in Go, all functions calls are done by value// (exceptions, see later)
    // a copy of input argument variables is passed o the function
    y := 5
    arr := [2]int{45, 99}
    s := "olo"
    doubleFail(y, arr, s)
    fmt.Println("outside doublefail", y, arr, s)
}

// where function is placed does not matter
// no overloading of function w/ different input parameters
func addNumbers(a int, b int) {
    fmt.Println(a + b)
}

func addInts(c int, d int) int {
    return c + d
}

// multiple returns
func divAndRemainder(e int, f int) (int, int) {
    return e / f, e%f
}

func doubleFail(a int, arr [2]int, s string)  {
    a = a * 2
    for index := 0; index < len(arr); index++ {
        arr[index] *= 2
    }
    s = s + s
    fmt.Println("in doublefail", a, arr, s)
}

Pointers

// pointers are used in C to simulate arrays and strings
package main

import "fmt"

// pointer as input parameter
func setTo10(pointerToInt *int) {
    *pointerToInt = 10
}

func setTo10Fail(pointerToInt *int) {
    fmt.Println("#setTo!(Fail pointer passed as argument =", pointerToInt)
    // will not affect the original pointer because passed by value
    pointerToInt = new(int)
    fmt.Println("#setTo!(Fail reassignment =", pointerToInt)

    // set the value in memory to 10
    *pointerToInt = 10
}

func main() {
    a := 10
    // & = reference / pointer to variable "a"
    // the value of b is the location where a is stored
    b := &a
    // c is a copy of "a" at a given time, // they are independent of each other after the first assignment
    c := a
    fmt.Println(a, b, *b, c)

    a = 20
    // to see the value inside the memory location use * // (de-reference the pointer and get to the value)
    fmt.Println(a, b, *b, c)

    // dereference the pointer and assign a value in memory
    // therefore the value of "a" also changes
    *b = 30
    fmt.Println(a, b, *b, c)

    c = 40
    fmt.Println(a, b, *b, c)

    // zero-value for a pointer is nil (absence of value)
    var d *int
    fmt.Println("value of d =", d)
    // cannot read or write value of a nil pointer
    // fmt.Println(*d)   // throws a panic

    e := new(int)
    // new keyword makes a pointer for the type
    fmt.Println("pointer to e =", e)
    // new also allocates memory, here to the zero-value forint type// therefore no panic
    fmt.Println("value of e =", *e)

    f := 20
    fmt.Println("value of f =", f)
    // we pass a pointer to f into that function
    setTo10(&f)
    fmt.Println("value of f after setTo10 =", f)

    g := 30
    fmt.Println("pointer to g =", &g)
    fmt.Println("value of g =", g)
    // on Go, variable in function calls are passed by VALUE
    setTo10Fail(&g)
    fmt.Println("pointer to g after #setTo10Fail =", &g)
    // you CANNOT change the pointer of a variable passed
    fmt.Println("value of g after #setTo10Fail =", g)
}

Arrays

package main

import "fmt"

func main() {
    // zero-value of arrays is an array// of specified length of zero-values of the type inside the array
    var myArrInt [4]int
    fmt.Println(myArrInt)

    myArrInt[0] = 12
    myArrInt[1] = 23
    myArrInt[2] = 34
    myArrInt[3] = 45
    fmt.Println(myArrInt)

    // one-line array assihnement in a composite literal expression
    // the length of the array is part of its type definition
    myArrInt = [4]int{111, 222, 333, 444}
    fmt.Println(myArrInt)

    myArrStr := [4]string{"titi", "tooi", "tatu", "teti"}
    fmt.Println(myArrStr)

    // iterate over an array
    for i, val := range myArrInt {
        fmt.Printf("At index %d = %d \n", i, val)
    }

    // slice of an array
    myArrStr2 := myArrStr[:2]

    // use _ to ignore the index variable
    for _, val := range myArrStr2 {
        fmt.Println(val)
    }
    // use of arrays is limited, slices are more flexible

}

Slices and Maps

package main

import "fmt"

func main() {
    /*
      SLICE = growable sequence of values of a single specified type
      the size is not part of the type definition
    */
    // define a slice in a composite literal expression
    myFiboSlice := []int{0, 1, 2, 3, 5, 8, 13}
    fmt.Println("myFiboSlice is", myFiboSlice)

    // create a slice from another slice = slice expression
    myFiboSlice2 := myFiboSlice[1:4]
    fmt.Println("myFiboSlice2 is", myFiboSlice2)

    // carefully with subslices because// they point to the same location in memory as the original slice
    myFiboSlice[2] = 00
    fmt.Println("\n myFiboSlice is", myFiboSlice)
    // slices are reference types, behave like pointers
    fmt.Println("myFiboSlice2 after modifying myFiboSlice is", myFiboSlice2)

    // zero-value for slice is nil slice (no value in slice)
    titiSlice := []string{"titi_one", "titi_two", "titi_three"}
    var totoSlice []string
    fmt.Println("totoSlice is", totoSlice)
    fmt.Println("length of totoSlice is", len(totoSlice))

    // assigning slice to another slice makes them share same location// in memrory
    totoSlice = titiSlice
    fmt.Println("totoSlice is now", totoSlice)
    titiSlice[0] = "titi_zero"
    fmt.Println("after modifying titiSlice, totoSlice is now", totoSlice)

    // this behavior also happens in functions
    modifySlice(titiSlice)
    fmt.Println("after modifying titiSlice in a function, totoSlice is now", totoSlice)

    // define a slice filled with wero-values of the type specified
    // last argument is the capacity of the underlying array
    s1 := make([]int, 5, 20)

    // copy a slice from another slice with the copy built-in function// "copy in slice s1 the elements of slice myFiboSlice
    copy(s1, myFiboSlice) 
    fmt.Println("\ns1 is", s1)

    // append built-in function -> returns a new slice
    // increases the length of the slice
    s2 := append(s1, 21, 34, 55)
    fmt.Println("s2 is", s2)

    // append a slice to another slice
    s3 := []int{111, 222, 333}
    // notice the ... after the s3 identier to spread the elements in it
    s3 = append(s2, s3...)
    fmt.Println("s3 is", s3)

    // deleting element at offset 6 (7th) from slice (the easy way)
    s3 = append(s3[:6], s3[7:]...)
    fmt.Println("s3 is", s3)

    // deleting from slice, the more involved way (see the function below)// it was tough to find a working algorithm !
    s3 = deleteItemFromSliceAtIndex(s3, 3)
    fmt.Println("s3 is", s3)

    // slices are based on an underlying array // for which you can specify the capacity // (number of spots to allocate in memory)
    // here the slice is initialized with 5 zero-value spots // but the underlying array has 100 spots in case we append.
    // This allows to avoid to copy and create a new underlying array // every time we append more than the length of the slice
    s4 := make([]int, 5, 100)
    fmt.Println("s4 is", s4)
    fmt.Println("length of s4 is", len(s4))
    fmt.Println("capacity of s4 is", cap(s4))

    // make a slice of bytes out of a string
    hello := "李先生你好"
    myByteSlice := []byte(hello)
    fmt.Println("\nmyByteSlice is", myByteSlice)

    myRuneSlice := []rune(hello)
    fmt.Println("\nmyRuneSlice is", myRuneSlice)

    // multidimensional slice
    s5 := []int{84, 64, 44}
    s6 := []int{42, 32, 22}
    s7 := [][]int{s5, s6}
    fmt.Println("\ns7 is", s7)

    /********** MAPS ****************/

    // associate value of single data type to value of another data type// collection of key / value pairs (key not restricted to a string)
    // maps are unordered

    myMap := make(map[string]string)
    myMap["name"] = "GOTO"
    myMap["firstname"] = "Florian"
    myMap["occupation"] = "Software Engineer"
    myMap["native_language"] = "French"
    fmt.Printf("\n%v\n", myMap)

    // access value in map
    fmt.Printf("The name is %v\n", myMap["name"])

    // if no value on a key return zero-value for the type of value
    fmt.Printf("The age is %v\n", myMap["age"])

    // make sure a key is in the map = comma ok idiom
    // v = value associated w/ existing key
    // ok = boolean is key in map
    if v, ok := myMap["isBillionaire"]; ok {
        fmt.Println("isBillionaire in map =", v)
    } else {
        // ok == false
        fmt.Println("isBillionaire in map =", ok)
    }

    // map literal declaration (composite literal expression)
    worldMap := map[int]string{
        // every line must end with a comma
        1: "nimefurahi kukuona",
        2: "приємно бачити вас",
        3: "तुम्हें देखकर अच्छा लगा",
        4: "ስለተያየን ደስ ብሎኛል",
        5: "ดีใจที่ได้พบคุณ",
    }

    // iterate over a map - order of iteration is random
    for keyInMap, valueInMap := range worldMap {
        fmt.Println(keyInMap, "=", valueInMap)
    }

    // delete value from map (built-in function)
    delete(worldMap, 2)
    fmt.Println("worldMap :", worldMap)

    // same as slices, maps are passed by reference

    // nil map
    var tMap map[string]int
    // writing to zero-valued map will make the program panic
    // tMap["toto"] = 12345678
    fmt.Println("tMap :", tMap)
    fmt.Println("length of tMap :", len(tMap))

    // delete an element in map
    sport := map[string]string{"yoyo": "ok", "ping pong": "great"}
    fmt.Println("sport :", sport)
    delete(sport, "yoyo")
    fmt.Println("sport :", sport)

    // to make sure that you delete an existing pair in the map
    langs := map[string]string{
        "ES6+":         "great",
        "Go":           "cool",
        "TypeScript":   "ok",
        "Python":       "over hyped but nice",
        "Bash":         "necessary",
        "HTML5":        "necessary",
        "CSS":          "necessary",
        "Elm":          "niche",
        "Java":         "no comments...",
        "Rust":         "to assess",
        "Web Assembly": "who knows",
    }
    fmt.Println("lang :", langs)
    if _, ok := langs["assembly"]; ok {
        delete(langs, "assembly")
    }
    fmt.Println("lang :", langs)

}

func modifySlice(s []string) {
    s[1] = "one"
    fmt.Println("\n", s)
}

func deleteItemFromSliceAtIndex(s []int, index int) []int {
    temp := make(map[int]int, len(s))
    // convert slice to map
    for i, v := range s {
        if i == index {
            continue
        }
        temp[i] = v
    }

    newSlice := make([]int, len(temp))

    for i := 0; i < len(temp); i++ {
        if i == index {
            // comma dot idiom = check if key in map
            value, ok := temp[i+1]

            // check that next index exists
            if ok && i <= len(temp) {
                newSlice[i] = value
                continue
            }
        }

        if i > index {
            newSlice[i] = temp[i+1]
            continue
        }

        newSlice[i] = temp[i]
    }

    return newSlice
}

I won’t go into concurrency and the like (Goroutines, channels…) here which are more advanced topics that make Go apart from other languages.

Keep learning new things, never stops !

Top Vue.js Developers in USA

Top Vue.js Developers in USA

Vue.js is an extensively popular JavaScript framework with which you can create powerful as well as interactive interfaces. Vue.js is the best framework when it comes to building a single web and mobile apps.

We, at HireFullStackDeveloperIndia, implement the right strategic approach to offer a wide variety through customized Vue.js development services to suit your requirements at most competitive prices.

Vue.js is an open-source JavaScript framework that is incredibly progressive and adoptive and majorly used to build a breathtaking user interface. Vue.js is efficient to create advanced web page applications.

Vue.js gets its strength from the flexible JavaScript library to build an enthralling user interface. As the core of Vue.js is concentrated which provides a variety of interactive components for the web and gives real-time implementation. It gives freedom to developers by giving fluidity and eases the integration process with existing projects and other libraries that enables to structure of a highly customizable application.

Vue.js is a scalable framework with a robust in-build stack that can extend itself to operate apps of any proportion. Moreover, vue.js is the best framework to seamlessly create astonishing single-page applications.

Our Vue.js developers have gained tremendous expertise by delivering services to clients worldwide over multiple industries in the area of front-end development. Our adept developers are experts in Vue development and can provide the best value-added user interfaces and web apps.

We assure our clients to have a prime user interface that reaches end-users and target the audience with the exceptional user experience across a variety of devices and platforms. Our expert team of developers serves your business to move ahead on the path of success, where your enterprise can have an advantage over others.

Here are some key benefits that you can avail when you decide to hire vue.js developers in USA from HireFullStackDeveloperIndia:

  • A team of Vue.js developers of your choice
  • 100% guaranteed client satisfaction
  • Integrity and Transparency
  • Free no-obligation quote
  • Portal development solutions
  • Interactive Dashboards over a wide array of devices
  • Vue.js music and video streaming apps
  • Flexible engagement model
  • A free project manager with your team
  • 24*7 communication with your preferred means

If you are looking to hire React Native developers in USA, then choosing HireFullStackDeveloperIndia would be the best as we offer some of the best talents when it comes to Vue.js.