Home >Backend Development >Golang >Understanding Go through the Lens of TypeScript/JavaScript
If you're coming from a TypeScript/JavaScript background and diving into Go, it can be helpful to draw parallels between the two languages to speed up your learning. While they are fundamentally different in many ways (Go being a statically-typed, compiled language, and TypeScript/JavaScript being dynamically typed, interpreted or transpiled languages), there are some useful analogies that will help make Go more intuitive.
In TypeScript, you define types and interfaces to describe the shape of objects. Similarly, Go has structs, which are used to define custom types. A struct can contain fields of different types, similar to how a TypeScript type or interface may contain different properties.
TypeScript:
type Book = { title: string; pages: number; read(): void; }
Go:
type Book struct { Title string Pages int } func (b Book) Read() { fmt.Println("Reading", b.Title) }
In both cases, you are defining the structure of an object. However, Go’s structs are more rigid and do not support inheritance, unlike TypeScript, which allows for more dynamic behavior with interfaces and class inheritance.
In JavaScript, when you define a method on an object’s prototype, it’s associated with instances of that object. Go uses a similar concept with receiver functions that are tied to a specific struct. This feels similar to how functions are attached to objects in JavaScript via prototypes.
JavaScript:
function Book(title, pages) { this.title = title; this.pages = pages; } Book.prototype.read = function() { console.log("Reading", this.title); }
Go:
type Book struct { Title string Pages int } func (b Book) Read() { fmt.Println("Reading", b.Title) }
In Go, the Read method has a receiver (b Book), which acts similarly to how methods are associated with prototypes in JavaScript. It gives you the object’s instance (b here), letting you access the fields and use the method.
The way you declare variables in Go is reminiscent of JavaScript’s let, var, and const. In Go, variables are declared with var, and constants with const, much like TypeScript.
TypeScript:
let name: string = "TypeScript"; const maxItems: number = 100;
Go:
var name string = "Go" const maxItems int = 100
The := shorthand in Go feels somewhat like JavaScript’s let in that it allows for quick variable declaration:
type Book = { title: string; pages: number; read(): void; }
In Go, there is no distinction between let and const like in JavaScript. By default, all variables in Go are mutable when declared with var, meaning their values can be changed later. If you want to make a variable immutable in Go, you must explicitly use the const keyword. Unlike JavaScript, where you have both let for mutable variables and const for immutable ones, in Go, everything is mutable unless you declare it as const.
TypeScript interfaces define the shape of objects, while Go interfaces define behavior (i.e., a set of methods an object must have). In Go, an object "implements" an interface implicitly by having all required methods, which contrasts with TypeScript's explicit implementation.
TypeScript:
type Book struct { Title string Pages int } func (b Book) Read() { fmt.Println("Reading", b.Title) }
Go:
function Book(title, pages) { this.title = title; this.pages = pages; } Book.prototype.read = function() { console.log("Reading", this.title); }
In Go, any type that implements the Read method is considered to implement the Reader interface, even without explicitly declaring it.
Error handling in Go feels very different compared to JavaScript’s try-catch. In Go, error handling is done explicitly with return values, while JavaScript uses exceptions.
JavaScript:
type Book struct { Title string Pages int } func (b Book) Read() { fmt.Println("Reading", b.Title) }
Go:
let name: string = "TypeScript"; const maxItems: number = 100;
In Go, errors are returned from functions and need to be checked explicitly, which leads to more predictable control flow but requires more manual error handling compared to JavaScript’s try-catch mechanism.
In TypeScript, you organize your code into modules that can import/export other pieces of functionality. Go has a similar package system where each file is part of a package, and packages can import functionality from other packages.
TypeScript:
var name string = "Go" const maxItems int = 100
Go:
name := "Go" // type inference, like in TypeScript
In Go, package main is the entry point of your application, similar to how a main file might serve as an entry point for a TypeScript project using ES modules.
JavaScript's asynchronous programming with async/await and promises feels somewhat analogous to Go’s goroutines. Goroutines allow functions to run concurrently, making Go’s concurrency model very powerful.
JavaScript:
interface Reader { read(): void; } class Book implements Reader { read() { console.log("Reading a book"); } }
Go:
type Reader interface { Read() } type Book struct { Title string } func (b Book) Read() { fmt.Println("Reading", b.Title) }
With Go's goroutines, you can launch functions concurrently with the go keyword, while TypeScript achieves this through async/await and promises.
Switching from TypeScript/JavaScript to Go might seem daunting at first, but drawing these comparisons can help make the transition smoother. Understanding Go's stricter type system, explicit interfaces, and concurrency model will make your journey rewarding. Once you get the hang of Go’s more explicit and structured nature, you’ll appreciate its performance and reliability in building robust systems.
The above is the detailed content of Understanding Go through the Lens of TypeScript/JavaScript. For more information, please follow other related articles on the PHP Chinese website!