Compare commits

..

2 Commits

Author SHA1 Message Date
15b2440d19 Fixed collections page of go 2024-11-18 19:41:20 +01:00
d17eb8dfce Started go section 2024-11-18 19:37:04 +01:00
13 changed files with 937 additions and 33 deletions

View File

@@ -9,31 +9,31 @@ import {
} from "./chunk-3YS4HNIT.js"; } from "./chunk-3YS4HNIT.js";
// node_modules/vitepress/dist/client/theme-default/index.js // node_modules/vitepress/dist/client/theme-default/index.js
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/fonts.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/fonts.css";
// node_modules/vitepress/dist/client/theme-default/without-fonts.js // node_modules/vitepress/dist/client/theme-default/without-fonts.js
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/vars.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/vars.css";
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/base.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/base.css";
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/utils.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/utils.css";
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/custom-block.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/custom-block.css";
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code.css";
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code-group.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code-group.css";
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/vp-doc.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/vp-doc.css";
import "C:/git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/vp-sponsor.css"; import "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/styles/components/vp-sponsor.css";
import VPBadge from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue"; import VPBadge from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
import Layout from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/Layout.vue"; import Layout from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/Layout.vue";
import { default as default2 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue"; import { default as default2 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue";
import { default as default3 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPImage.vue"; import { default as default3 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPImage.vue";
import { default as default4 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPButton.vue"; import { default as default4 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPButton.vue";
import { default as default5 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue"; import { default as default5 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue";
import { default as default6 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue"; import { default as default6 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue";
import { default as default7 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue"; import { default as default7 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue";
import { default as default8 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue"; import { default as default8 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue";
import { default as default9 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue"; import { default as default9 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue";
import { default as default10 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue"; import { default as default10 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue";
import { default as default11 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue"; import { default as default11 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue";
import { default as default12 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue"; import { default as default12 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue";
import { default as default13 } from "C:/git/docs/node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue"; import { default as default13 } from "/Users/djdietrick/Git/docs/node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue";
// node_modules/vitepress/dist/client/shared.js // node_modules/vitepress/dist/client/shared.js
var inBrowser = typeof document !== "undefined"; var inBrowser = typeof document !== "undefined";

View File

@@ -1,31 +1,31 @@
{ {
"hash": "cb1f9d5c", "hash": "b31dd5f2",
"configHash": "9ebaad5b", "configHash": "9af315cb",
"lockfileHash": "6f849b3a", "lockfileHash": "951d497c",
"browserHash": "c342cb39", "browserHash": "14d9b0dd",
"optimized": { "optimized": {
"vue": { "vue": {
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js", "src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
"file": "vue.js", "file": "vue.js",
"fileHash": "d958a5e2", "fileHash": "9f6650f2",
"needsInterop": false "needsInterop": false
}, },
"vitepress > @vue/devtools-api": { "vitepress > @vue/devtools-api": {
"src": "../../../../node_modules/@vue/devtools-api/dist/index.js", "src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
"file": "vitepress___@vue_devtools-api.js", "file": "vitepress___@vue_devtools-api.js",
"fileHash": "7d35fe85", "fileHash": "87d887f1",
"needsInterop": false "needsInterop": false
}, },
"vitepress > @vueuse/core": { "vitepress > @vueuse/core": {
"src": "../../../../node_modules/@vueuse/core/index.mjs", "src": "../../../../node_modules/@vueuse/core/index.mjs",
"file": "vitepress___@vueuse_core.js", "file": "vitepress___@vueuse_core.js",
"fileHash": "c964aa0c", "fileHash": "3179a954",
"needsInterop": false "needsInterop": false
}, },
"@theme/index": { "@theme/index": {
"src": "../../../../node_modules/vitepress/dist/client/theme-default/index.js", "src": "../../../../node_modules/vitepress/dist/client/theme-default/index.js",
"file": "@theme_index.js", "file": "@theme_index.js",
"fileHash": "8c3760fb", "fileHash": "1bd77338",
"needsInterop": false "needsInterop": false
} }
}, },

View File

@@ -15,6 +15,7 @@ export default {
"/interview/": require("../interview/sidebar.json"), "/interview/": require("../interview/sidebar.json"),
"/server/": require("../server/sidebar.json"), "/server/": require("../server/sidebar.json"),
"/aws/": require("../aws/sidebar.json"), "/aws/": require("../aws/sidebar.json"),
"/go": require("../go/sidebar.json"),
"/": [ "/": [
{ {
text: "Home", text: "Home",

View File

@@ -0,0 +1,173 @@
# Collections
## Arrays
Arrays in Go are fixed length and must be declared at initialization.
```go
var a [10]int
a[0] = 1
```
## Slices
A slice is like an array but it does not have a fixed size. You can further slice a slice be specifying a low and high index, inclusive of the first and exclusive of the last.
```go
primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[1:4]
fmt.Println(s) // 3 5 7
s = primes[3:] // 7, 11, 13
s = primes[:2] // 2, 3
```
Slices are references to an underlying array, so if you create a slice of an array and edit that slice, you will also edit the underlying array.
```go
names := [4]string{
"John",
"Paul",
"George",
"Ringo",
}
fmt.Println(names) // John Paul George Ringo
a := names[0:2]
b := names[1:3]
fmt.Println(a, b) // John Paul, Paul George
b[0] = "XXX"
fmt.Println(a, b) // John XXX, XXX George
fmt.Println(names) // John XXX George Ringo
```
### Length vs Capacity
The length of a slice is how many items are actually stored in the array, and the capacity is how many slots the array has. A slice is considered a nil slice if it has 0 length and capacity and no underlying array.
```go
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
printSlice(s)
// Slice the slice to give it zero length.
s = s[:0]
printSlice(s)
// Extend its length.
s = s[:4]
printSlice(s)
// Drop its first two values.
s = s[2:]
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
// Output
// len=6 cap=6 [2 3 5 7 11 13]
// len=0 cap=6 []
// len=4 cap=6 [2 3 5 7]
// len=2 cap=4 [5 7]
```
You can create slices with specific length and capacity using `make`.
```go
x := make([]int, 0, 5) // len(x)=0, cap(x)=5
x = x[:cap(x)] // len(x)=5, cap(x)=5
x = x[1:] // len(x)=4, cap(x)=4
a := make([]int, 5)
// a len=5 cap=5 [0 0 0 0 0]
b := make([]int, 0, 5)
// b len=0 cap=5 []
c := b[:2]
// c len=2 cap=5 [0 0]
d := c[2:5]
// d len=3 cap=3 [0 0 0]
```
### Appending
If the underlying array of the slice is too small to accommodate the new elements, the returned slice will point to a newly allocated array.
```go
var s []int
// len=0 cap=0 []
// append works on nil slices.
s = append(s, 0)
// len=1 cap=1 [0]
// The slice grows as needed.
s = append(s, 1)
// len=2 cap=2 [0 1]
// We can add more than one element at a time.
s = append(s, 2, 3, 4)
// len=5 cap=6 [0 1 2 3 4]
```
## Maps
Maps are key-value pairs. They can be created with `make`.
```go
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex // cannot be used
func main() {
m = make(map[string]Vertex) // now can be used
m["Bell Labs"] = Vertex{
40.68433, -74.39967,
}
fmt.Println(m["Bell Labs"])
// Map literal
var n = map[string]Vertex{
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}
// Shorthand
var o = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
}
```
### Manipulating the map
```go
m[key] = elem
elem = m[key]
delete(m, key)
// Check if element exists
elem, ok = m[key]
```

View File

@@ -0,0 +1,205 @@
# Cocurrency
One of the strengths of Go is the simplicity of its cocurrency paradigm. A `goroutine` is essentially a thread that gets managed by the runtime.
```go
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
```
## Channels
Channels are typed pipelines that you can send and receive values between goroutines. Sending and receiving through a channel block the thread until the otherside is ready.
```go
ch := make(chan int)
ch <- v // Send v to channel ch.
v := <-ch // Receive from ch, and assign value to v.
```
```go
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}
```
### Buffering
Channels can also be buffered to allow senders to continue sending messages to a channel as long as the buffer is not full. Receivers block when the buffer is empty.
```go
ch := make(chan int, 100)
```
### Closing
Channels can be closed to denote when no more values are going to be sent through the channel. Receivers can test for a closed channel by receiving a second parameter from the channel. `ok` will be false if the channel is closed. The sender should always close the channel, as sending on a closed channel will cause a panic.
```go
v, ok := <-ch
close(ch)
```
This can also be used with `range` to automatically receive the values from the channel and break the loop after the channel closes.
```go
package main
import (
"fmt"
)
func fibonacci(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x+y
}
close(c)
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c {
fmt.Println(i)
}
}
```
### Select
Select is like a switch statement for channels. It blocks until a condition occurs and then runs that condition. If multiple are ready at the same time it will choose randomly. You can add a default case to do something without blocking.
```go
package main
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
func bomb() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
bomb()
}
```
## Mutex
Mutexes can be used to pass variables to multiple goroutines and making sure only one can operate on it at a time.
```go
package main
import (
"fmt"
"sync"
"time"
)
// SafeCounter is safe to use concurrently.
type SafeCounter struct {
mu sync.Mutex
v map[string]int
}
// Inc increments the counter for the given key.
func (c *SafeCounter) Inc(key string) {
c.mu.Lock()
// Lock so only one goroutine at a time can access the map c.v.
c.v[key]++
c.mu.Unlock()
}
// Value returns the current value of the counter for the given key.
func (c *SafeCounter) Value(key string) int {
c.mu.Lock()
// Lock so only one goroutine at a time can access the map c.v.
defer c.mu.Unlock()
return c.v[key]
}
func main() {
c := SafeCounter{v: make(map[string]int)}
for i := 0; i < 1000; i++ {
go c.Inc("somekey")
}
time.Sleep(time.Second)
fmt.Println(c.Value("somekey"))
}
```

108
docs/go/basics/control.md Normal file
View File

@@ -0,0 +1,108 @@
# Control Flow
For the most part, control flow keywords in Go do not require parenthesis `()` for the conditional statements but do require brackets `{}` to contain the logic.
## For loops
For loops in Go are similar to C++ in that they have an inital, conditional, and post statement in the declaration. Initial and post statements are optional if not needed. In that case, this becomes Go's `while` loop. You can go even further by dropping the condition all together to create an forever loop.
```go
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
// While
sum = 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
// Forever loop
for {
// repeats forever
}
}
```
You can use the `range` keyword to iterate over a slice or map. With a slice, you will get both the index and a copy of the element for each iteration.
```go
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range pow { // i or v can be ignored with _
fmt.Printf("2**%d = %d\n", i, v)
}
```
## If/Else
If statements in Go can also include short statements to execute before the condition, and variables in these statements are scoped to the if/else block.
```go
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
else if v == lim {
fm.Printf("%g == %g\n", v, lim)
}
else {
fmt.Printf("%g >= %g\n", v, lim)
}
return lim
}
```
## Switch
In Go, only the matching case is run, meaning you do not need to include `break` like you would in C++. The switch case stops evaluating after one of the cases matches, so you can not run multiple cases even if it matches multiple. Switch can also be written with no condition, effectively turning it into a long if/else block.
```go
import (
"fmt"
"runtime"
"time"
)
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
fmt.Printf("%s.\n", os)
}
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
```
## Defer
Defer can be used to delay a function call until the surrounding function returns. Defers can be stacked, and will execute on a last-in, first-out order.
```go
package main
import "fmt"
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
```

113
docs/go/basics/functions.md Normal file
View File

@@ -0,0 +1,113 @@
# Functions
Functions are declared with the `func` keyword. They can have zero or more arguments, and the types of the arguments come after the names with a space. Functions can also return multiple values, and this is how error checking is done in Go. You can even instantiate the return values of the function in the function definition (only use in short functions).
By default, arguments are passed by value. To pass by reference, you need to take a pointer as the argument to modify the reference.
```go
package main
import "fmt"
func add(x int, y int) int {
return x + y
}
func swap(x, y string) (string, string) {
return y, x
}
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(add(42, 13))
fmt.Println(swap("foo", "bar"))
fmt.Println(split(17))
}
```
Functions can also be saved as variables and passed to other functions.
```go
package main
import (
"fmt"
"math"
)
func compute(fn func(float64, float64) float64) float64 {
return fn(3, 4)
}
func main() {
hypot := func(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
fmt.Println(hypot(5, 12))
fmt.Println(compute(hypot))
fmt.Println(compute(math.Pow))
}
```
## Closures
Closures are functions that reference variables outside of the function body. In the below example, the inner function of `adder` has access to its own sum.
```go
package main
import "fmt"
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
pos(i),
neg(-2*i),
)
}
}
// 0 0
// 1 -2
// 3 -6
// 6 -12
// 10 -20
// 15 -30
// 21 -42
// 28 -56
// 36 -72
// 45 -90
```
## Generics
Functions can also take generic types with the below syntax. In the below example the generic type must implement the `comparable` constraint, meaning it has the `==` and `!=` operators.
```go
func Index[T comparable](s []T, x T) int {
for i, v := range s {
// v and x are type T, which has the comparable
// constraint, so we can use == here.
if v == x {
return i
}
}
return -1
}
```

View File

@@ -0,0 +1,19 @@
# Packages
Every Go program is made up of packages. When importing packages into a file, it is proper to use factored import statements, meaning combining all of the imports within parenthesis. The `main` package symbolizes code that will be run as a binary. Otherwise the package is a library.
Only names starting with Capital letters are exported from a package (public). Lowercase names will remain private within the package.
```go
package main
import (
"fmt"
"math"
)
func main() {
fmt.Printf("Now you have %g problems.\n", math.Sqrt(7))
}
```

View File

@@ -0,0 +1,25 @@
# Pointers
Pointers, like C++, hold memory addresses of a value. The zero value of a pointer is `nil`. Pointers are declared with `*T` which is a pointer to type T. The `&` operator creates a pointer to its operand. You can access the pointer value with `*` to get and set.
```go
var p *int
i := 42
p = &i
fmt.Println(*p)
*p = 21
```
## Structs
To access values of a struct you are referencing with a pointer, you can use the shorthand of the `.` operator to access the value.
```go
type Vertex struct {
X int
Y int
}
p := &Vertex{1,2}
fmt.Println(p.Y)
p.X = 4
```

164
docs/go/basics/struct.md Normal file
View File

@@ -0,0 +1,164 @@
# Structs
Structs are collections of fields. They are defined as types and then created using brackets to declare the values.
```go
import (
"fmt"
)
type Vertex struct {
X int
Y int
}
v := Vertex{1, 2}
v2 := Vertex{X: 2, Y: 4}
fmt.Println(v.X)
```
## Methods
Go does not have classes. Instead, functions can have `receivers` which relates to an instance of a struct and gets passed to the function. Methods can only be defined with a receiver that is in the same package, including built-in types.
By default, receivers are passed by value meaning any modifications to the receiver will not stick to the initial object. You can pass pointers as receivers to pass by reference and modify the reference. While functions require you to explicitly pass a pointer or a value, methods will automatically call the pointer method on a normal object and vice versa. In the below example, we call Scale on `v` and not `(%v).Scale(10)`. Pointer receivers also don't require you to copy the object which can be expensive for larger objects.
```go
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs()) // 5
v.Scale(10)
fmt.Println(v.Abs()) // 50
}
```
## Interfaces
Interfaces are definitions of structs that all implement the declared methods. One note is that if the type implements the method with a pointer receiver, then the pointer to that class is considered that interface but the underlying type is not (If M took a \*T, then you would not be able to instantiate an instance of T as I).
```go
package main
import "fmt"
type I interface {
M()
}
type T struct {
S string
}
// This method means type T implements the interface I,
// but we don't need to explicitly declare that it does so.
func (t T) M() {
fmt.Println(t.S)
}
func main() {
var i I = T{"hello"}
i.M()
}
```
You can also check that a pointer is nil within the function to gracefully handle nil pointer exceptions at the function level.
```go
type T struct {
S string
}
func (t *T) M() {
if t == nil {
fmt.Println("<nil>")
return
}
fmt.Println(t.S)
}
```
### Empty Interfaces
Empty interfaces in Go are essentially an `any` type.
```go
package main
import "fmt"
func main() {
var i interface{}
// (<nil>, <nil>)
i = 42
// (42, int)
i = "hello"
// (hello, string)
}
type any interface{}
```
### Type Assertions
To check if an instance of an interface is actually an instance of an underlying class, you can check with the below syntax.
```go
t := i.(T) // Will panic if not type T
t, ok := i.(T) // Returns T instance and true if that type, or zero-value of T and false if not
// With switch
switch v := i.(type) {
case T:
// here v has type T
case S:
// here v has type S
default:
// no match; here v has the same type as i
}
```
### Common Interfaces
#### Stringers
This is an object that has a function to describe itself as a string. Many functions from `fmt` look for this method.
```go
type Stringer interface {
String() string
}
```
#### Errors
Return a string when the error occurs.
```go
type error interface {
Error() string
}
```

View File

@@ -0,0 +1,84 @@
# Variables and Types
Variables are declared using the `var` keyword or using the initial assignment operator `:=` (only inside functions). The type of the variable comes last, and can be inferred if using the assignment operator. Variables can be at the package or function level. You can also declare constants with the `const` keyword, but cannot use the `:=` operator. Numeric constants can be used for high precision.
```go
package main
import "fmt"
var c, python, java bool
func main() {
var i int
j := 3 // int inferred
const k = "Can't change this"
const Big = 1 << 100 // 1 shifted left 100 times
fmt.Println(i, c, python, java)
}
```
## Types
The basic types in go are:
- bool
- string
- int, int8, int16, int32, int64
- uint, uint8, uint16, uint32, uint64, uintptr
- byte (alias for uint8)
- rune (alias for int32, represents a Unicode code point)
- float32, float64
- complex64, complex128
```go
package main
import (
"fmt"
"math/cmplx"
)
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmplx.Sqrt(-5 + 12i)
)
func main() {
fmt.Printf("Type: %T Value: %v\n", ToBe, ToBe) // bool, false
fmt.Printf("Type: %T Value: %v\n", MaxInt, MaxInt) // uint64, 18446744073709551615
fmt.Printf("Type: %T Value: %v\n", z, z) // complex128, (2+3i)
}
```
### Default Values (Zero values)
When not given an initial value, the below types default to:
- bool - false
- string - ""
- numeric - 0
### Type Conversion
You can cast variables to different types by specifying the type in the below syntax.
```go
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
```
### Generic Types
Types can also be generic to work with multiple different types of arguments.
```go
// Singly linked list
type Node[T any] struct {
next *Node[T]
val T
}
```

View File

@@ -1,6 +1,16 @@
[ [
{ {
"text": "Go Basics", "text": "Go Basics",
"items": [{ "text": "Introduction", "link": "/go/" }] "items": [
{ "text": "Introduction", "link": "/go/" },
{ "text": "Packages", "link": "/go/basics/packages" },
{ "text": "Variables and Types", "link": "/go/basics/variables" },
{ "text": "Functions", "link": "/go/basics/functions" },
{ "text": "Control Flow", "link": "/go/basics/control" },
{ "text": "Collections", "link": "/go/basics/collection" },
{ "text": "Pointers", "link": "/go/basics/pointers" },
{ "text": "Structs", "link": "/go/basics/struct" },
{ "text": "Concurrency", "link": "/go/basics/concurrency" }
]
} }
] ]

View File

@@ -3,3 +3,5 @@
[Python](/python/) [Python](/python/)
[Rust](/rust/) [Rust](/rust/)
[Go](/go/)