Golang
It's mostly complete, but needs to be touched upon.
Types
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
Printing
import fmt
fmt.Printf("string")
fmt.Printf(variable)
%v -> value
%s -> string
%d -> int
%.2f -> float with 2 decimals
fmt.Sprintf("Hello %v", "world")
fmt.Sprintf("Hello %s", "world")
Strongly typed
var first_name string = "Gary"
last_name := "Feng"
var age = 2.6
short_age := int(age)
//age = 24.6
//short_age = 24
const gender = "M"
Both are string, walrus := will "infer" the type to assign the variable
IF ELSE
if length1 < length2{
asd
} else if length1 > length2{
asd
} else {
asd
}
if length := getLength(variable); length < 1 {
}
if you want to make a variable inside the scope
Switch Case
func name(plan string) float64{
switch plan{
case "free":
return 10.0
case "pro":
return 20.0
default:
return 30.0
}
}
blank identifier
_ can discard a return value
x, _ := getXY()
So if a function returns 2 values like getXY() but we only care about the x, we can use _ to discard the value.
Named return
func getName()(first String, last String){
//first and last are intialized with no values
return //will return first and last if left blank
}
Struct
Go doesn't have inheriance or classes, but struct's sort of allows data only inheriance
type car struct {
model string
speed int
name string
color string
cost float64
}
func (myCar car) isCar() bool{
//check if myCar is a valid car
return true or false
}
fmt.Println(myCar.isCar())
//true or false
Memory layout matters
type stats struct {
Reach uint16
NumPosts uint8
NumLikes uint8
}
Notice how it's 16 then 8 then 8. if the memory is 8 then 16 then 8. It will add padding which will waste memory space.
reflect package can help debug memory layout
empty := struct{}{}
this is an empty struct.
type emptyStruct struct{}
empty := emptyStruct{}
this is a named empty struct. They are used as unary values. Both of these take 0 bytes. Example of a function for a structure.
func (myUser User) SendMessage (message string, messageLength int) (string, bool) {
if messageLength <= myUser.Membership.MessageCharLimit {
return message, true
}
return "", false
}
Send message is the method for User struct. It takes in message and messageLength as the parameter and returns a string and boolean. An example of using this method is
Bob := User{
//stuff
}
Bob.SendMessage("Hello World", 11)
\> > RE ORGANIZE THIS < <
Interface
A collection of method signatures.
map[string]any
Variadic
import package
func sum(nums ...int) int{
sum := 0
for i := 0; i < len(nums); i++{
sum += nums[i]
}
return sum
}
Notice the ... before int. It takes an abirtary number of final arguments.
// func make([]T, len, cap) []T
mySlice := make([]int, 5, 10)
Append
i := make([]int, 3, 8)
fmt.Println("len of i:", len(i))
// len of i: 3
fmt.Println("cap of i:", cap(i))
// cap of i: 8
fmt.Println("appending 4 to j from i")
// appending 4 to j from i
j := append(i, 4)
fmt.Println("j:", j)
// j: [0 0 0 4]
fmt.Println("addr of j:", &j[0])
// addr of j: 0x454000
fmt.Println("appending 5 to g from i")
// appending 5 to g from i
g := append(i, 5)
fmt.Println("addr of g:", &g[0])
// addr of g: 0x454000
fmt.Println("i:", i)
// i: [0 0 0]
fmt.Println("j:", j)
// j: [0 0 0 5]
fmt.Println("g:", g)
// g: [0 0 0 5]
Slices (Arrays)
var myInts[10]
slice of size 10
primes := [6]int{1,2,3,4,5,6}
slices
primes[1:4]
Loops
for i := 0; i < len(something); i++{
}
for i, ele := range slice{
}
Maps
to make a map in go, need to use make method
dict := make(map[string]int)
this is a map of key string to int value.
Pointers
Uses \ and &
ADD CODE SNIPPET
Channels
Channel creation
ch <- make(chan int, len(size))
Sending to channel
ch <- 5
Receiving from channel
x := <-ch
Close channel
close(ch) / defer close(ch)
Check if closed
if value, ok := <-ch; !ok{
fmt.Println("ch closed")
}
if sending data to closed channel. It will panic. Reciving from closed channel will result in 0.
Type safety
Read onlyfunc name(chan <-chan string)
Write only func name(chan chan<- string
Select statement
select{
case:
default:
}
Code snippet
import "time"
func processMessages(messages []string) []string {
ch := make(chan string, len(messages))
for _, message := range messages{
go func(msg string){
ch <- process(msg)
}(message)
}
processedMsgs := make([]string, len(messages))
for i := 0; i < len(messages); i++{
processedMsgs[i] = <-ch
}
return processedMsgs
}
func process(message string) string {
time.Sleep(1 time.Second)
return message + "-processed"
}
Mutexes
Generics
func lastT any T {
if len(s) == 0 {
var zero T
return zero
}
return s[len(s)-1]
}
T is the generic variable name. any allows it to be a generic in order for there to be a 0 generic.
Constraints
If you want only certain generics/types then you can make an interface
type numbers interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
~float32 | ~float64 |
}
func doMathT numbers T {
//do something and return a T type
}
Enum
Not that well supported in Go.
type perm string
const (
Read perm = "read"
Write perm = "write"
Exec perm = "execute"
)
var Admin = "admin"
var User = perm("user")
func checkPermission(p perm) {
// check the permission
}
type emailStatus int
const (
emailBounced emailStatus = iota
emailInvalid
emailDelivered
emailOpened
)
iota will make
emailBounces: 0
emailInvalid: 1
emailDelivered: 2
emailOpened: 3
HTTPS
ADD CODE SNIPPET
JSON
type Item struct{
Id string json:"id"
Name string json:"name"
ItemLevel int json:"item_level"
}
func getJSONtoGoStruct(url string) ([]Item, error){
res, res_err := http.Get(url)
defer res.Body.Close() //to prevent mem issue
var items []Items
decoder := json.NewDecoder(res.Body)
err := decoder.Decode(&items)
------------------------------------OR----------------------------------------
data []byte, err := io.ReadAll(res.Body)
json.Unmarshal(data, &items)
return items
}
Makes a GET request and turns the result into a Go struct
data, err := json.Marshal(items)
Turns a go struct into a []bytes
CRUD
func createPostReq(url, apiKey string, user User)(User, err){
jsonData, err := json.Marshal(data)
//err check
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
//err check
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", apiKey)
client := &http.Client{}
res, err := client.Do(req)
//err check
defer res.Body.Close()
var newUser User
decoder := json.NewDecoder(res.Body)
err = decoder.Decode(&newUser)
//err check
return data, nil
}
http:NewRequest("GET/POST/PUT/DELETE", url, nil/bytes.NewBuffer(jsonData))
brew install postgresql@16
brew services start postgresql
/opt/homebrew/opt/postgresql@16/bin/psql --version
echo 'export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH"' >> ~/.zshrc
psql --version
brew services start postgresql@16
psql postgres
CREATE DATABASE gator;
\c gator
SELECT version();