notes

key features

        simplicity

        fast compile times

        garbagy collected

        buillt-in concurrency

        compile to standalone binaries

strong and statically typed

Variable declaration

        var foo int

        var foo int = 42

        foo := 42

Cannot redeclare variables, but can shadow them

All variables must be used

Visibility

        lower case first letter for package scope

        upper case first letter to export

        no private scope

Naming conventions

         Pascal or camelCase

                capitalize acronyms(HTTP,URL)

        As short as reasonable

                longer names for longer lives

Type conversions

        destinationType(variable)

        use strconv package for strings

Primitives

        Boolean type

                zero boolean as false

        Numeric types

                Intergers

                        Signed intergers

                                int type has varying size, but min 32 bits

                                8 bit(int8) through 64 bits(int64)

                        Unsigned integers

                                8 bit(byte and uint8) through 32 bit(uint32)

                        Arithmetic operations

                                addition, subtraction, multiplication, division, remainder

                        Bitwise operations

                                and, or, xor, and not

                        Zero value is 0

                        cannot mix types in the same family

                Floating point

                        IEEE-754 standard

                        zero value is 0

                        32 and 64 bit versions

                        Literal styles

                                decimal  3,14

                                exponential 13e18 or 2e10

                                mixed 13.7e12

                        Arithmetic operations

                                addition, subtraction, multiplication, division

                Complex numbers

                        zero values is 0 +0i

                        64 and 128 nits versions

                        built-in functions

                                comlex - make complex number from floart

        Text types

                Strings

                        UTF-8

                        Immutable

                        Cab be concatenated with + operator

                        can be converted to []byte

n := 10             // 1010
    m := 3              //0011
    fmt.Println(n & m)  // 0010
    fmt.Println(n | m)  // 1011
    fmt.Println(n ^ m)  // 1001
    fmt.Println(n &^ m) // 0100
    

// You can edit this code!
// Click here and start typing.
package main

import "fmt"

// const a int16 = 27

const (
	a = iota
	b
	c
)

const (
	a2 = iota
)

const (
	//errSpecialList = iota
	_ = iota + 5
	catSpecialist
	dogSpecialist
	snakeSpecialist
)

const (
	_  = iota
	KB = 1 << (10 * iota)
	MB
	GB
	TB
	PB
	EB
	ZB
	YB
)

const (
	isAdmin = 1 << iota
	isHeadquarters
	canSeeFinancials

	canSeeAfica
	canSeeAsia
	canSeeEurope
	canSeeNorthAmerica
	canSeeSouthAmerica
)

func main() {

	var role byte = isAdmin | canSeeFinancials | canSeeEurope
	fmt.Println(canSeeAfica)
	fmt.Printf("%b\n", role)
	fmt.Printf("Is admin? %v\n", isAdmin&role == isAdmin)
	fmt.Printf("Is HQ? %v\n", isHeadquarters&role == isHeadquarters)
	fmt.Printf("HQ? %v\n", isHeadquarters&role)

	fileSize := 400000000000.
	fmt.Printf("%.2fGB \n", fileSize/GB)

	var specilistType int
	fmt.Printf("%v\n", specilistType == catSpecialist)
	fmt.Printf("%v\n", catSpecialist)

	//const a = 14
	//var b int16 = 17
	fmt.Printf("%v, %T\n", a, a)
	fmt.Println(b)
	fmt.Println(c)
	fmt.Println(a2)
}


    fmt.Printf("%v, %T\n", m, m)
    fmt.Println("Hello, 世界")

    a := 8
    fmt.Println(a << 3) // 8 * 2^3 = 2^6 = 64
    fmt.Println(a >> 3) // 2^3 / 2 ^3 = 2^0 = 1

    k := 13.43
    l := 3.2
    fmt.Println(k + l)
    fmt.Println(k - l)
    fmt.Println(k * l)
    fmt.Println(k / l)

Constant

Naming convention

Typed constant

untyped constant

enumerated constant

IMMUTABLE, BUT CAN BE SHadowed

replaced by the compiler at compile time

        values must be calculated at compile time

named like variables

        PascalCase for exported constants

        camelCase for internal constants

Typed constants work like immutable variables

        can interoperate only with same type

untyped constants work ike literals

        can inter

Enumerated constants

Enumerated expressions

// You can edit this code!
// Click here and start typing.
package main

import "fmt"

func main() {

	a := []int{}
	fmt.Println(a)
	a = append(a, 1)
	a = append(a, []int{2, 3, 4, 5}...)
	fmt.Println(a)

	b := a[1:]
	fmt.Println(b)
	fmt.Println(a)
	d := a[:len(a)-1]
	fmt.Println(d)
	e := append(a[:2], a[3:]...)
	fmt.Println(e)
	fmt.Println(a)

	c := make([]int, 3, 100)
	fmt.Println(c)

	grades := [3]int{75, 43, 32}
	fmt.Printf("grades : %v \n", grades)

	var students [3]string
	students[0] = "lida"
	fmt.Printf("students : %v \n", students)
	fmt.Printf("student : %v \n", students[0])

	//a := [...]int{1, 2, 3}
	//b := &a
	//b[1] = 5
	//fmt.Println(a)
	//fmt.Println(b)

	//a := []int{1, 2, 3}
	//b := a
	//b[1] = 5
	//fmt.Println(a)
	//fmt.Println(cap(a))
	//fmt.Println(len(a))
	//fmt.Println(b)

}

Arrays

        Creation

        Built-in functions

        Working with arrays

        Collection of items with same type

        fixed size

        declaration styles

        access via zero-based index

        len() returns size of array

        copies refer to different underlying data

Slices

        Creation

        Built-in functions

        Working with arrays

        backed by array

        Creation styles

                slice exsting array or slice

                lireral stlyle

                via make function

        len()

        cap()

        append()

        copies refer to same underlying array

Maps

        what are they?

        Creating

        Manipulation

        Collections of values types that are accessed by keys

        Check for presence with "value,ok" form of result

        multiple assignments point to the same underlying data

Structs

        what are they?

        Creating

        Naming conventions

        Embedding

        Tags

        Collectiosn of disparate data types that dscribe a single convept

        Keys are named fields

        structs are value types

        anonymous structs are allowed

        No inheritance, but can use compisition via embedding

        tags can be added to struct fields to describe field

// You can edit this code!
// Click here and start typing.
package main

import (
	"fmt"
	"reflect"
)

type Doctor struct {
	number     int
	actorName  string
	episodes   []string
	companions []string
}

type Animal struct {
	Name   string `required max:"100"`
	Origin string
}
type Bird struct {
	SpeedKPH float32
	CanFly   bool
	Animal
}

func main() {

	t := reflect.TypeOf(Animal{})
	field, _ := t.FieldByName("Name")
	fmt.Println(field.Tag)

	b := Bird{}
	b.Name = "Emu"
	b.Origin = "Australia"
	b.SpeedKPH = 48
	b.CanFly = false
	b = Bird{
		Animal: Animal{Name: "Emuasd", Origin: "Australia"},
	}
	fmt.Println(b.Name)

	statePopulations := map[string]int{
		"california": 109349057,
		"texas":      9273459,
		"florida":    9348590743,
	}
	pop, ok := statePopulations["california"]
	fmt.Println(pop, ok)
	m := map[[3]int]string{}
	fmt.Println(statePopulations["california"], m)

	a := make(map[string]int)
	a["georgia"] = 1923748
	delete(a, "georgia")
	fmt.Println(a["georgiappp"])

	sp := statePopulations
	delete(sp, "texas")
	fmt.Println(statePopulations, sp)

	aDoctor := Doctor{
		number:     3,
		actorName:  "john",
		companions: []string{"fs", "sfd"},
	}
	fmt.Println(aDoctor)

	bDoctor := struct{ name string }{name: "John Pertwee"}
	fmt.Println(bDoctor)
	anotherDoctor := &aDoctor
	anotherDoctor.actorName = "Tom"
	fmt.Println(anotherDoctor)
	fmt.Println(aDoctor)

	fmt.Println("Hello, 世界")
}

If statements

        Initializer

        Comparison operators

        Logical operators

        Short circuiting

        If-else statement

        If-else-if statement

        Equality and floats

switch statement

        switching on  a tag

        cases with multiple tests

        initializers

        switches with no tag

        fallthrough

package main

import (
	"fmt"
	"log"
)

func panicker() {
	fmt.Println("about to panic")
	defer func() {
		if err := recover(); err != nil {
			log.Println("Error:", err)
			panic(err)
		}
	}()
	panic("something happed")
	fmt.Println("Done panic")
}
func main() {
	fmt.Println("start")
	panicker()
	fmt.Println("end")

	// http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	// 	w.Write([]byte("hello world"))
	// })
	// err := http.ListenAndServe(":8088", nil)
	// if err != nil {
	// 	panic(err.Error())
	// }

	// a := "start"
	// defer func() {
	// 	if err := recover(); err != nil {
	// 		log.Println("Error:", err)
	// 	}
	// }()
	// //defer fmt.Println("this war derferd")
	// panic("something happed")
	// a = "end"
	// fmt.Println(a)

	// a, b := 1, 0
	// ans := a / b
	// fmt.Println(ans)

	//res, err := http.Get("https://www.google.com/robots.txt")
	// res, err := http.Get("https://cybernetist.com/2020/05/18/getting-started-with-go-ldap/")

	// if err != nil {
	// 	log.Fatal(err)
	// }
	// defer res.Body.Close()
	// robots, err := ioutil.ReadAll(res.Body)
	// if err != nil {
	// 	log.Fatal(err)
	// }
	// fmt.Printf("%s", robots)

	// a := "start"
	// defer fmt.Println(a)
	// a = "end"

}

Defer

        used to delay execution of a statement until function exists

        useful to group "open" and "close" function together

                be careful in loops

        Run in LIFO (last-in, first-out) order

        arguments evaluated at time defer is executed , not at the time of function called

Panic

        Occur when program can not continue at all

                donot use when file can not be opened, unless it is critical

                use for unrecoverable events - can not obtain TCP port for web server

        Function will stop executing

                deferred functions will still fire

        if nothign handles panic, program will exit

        Recover

                used to recover from panics

                only useful in deferred functions

                Current function will not attempt to continue, but higher functions in call stack will

package main

import (
	"fmt"
)

type myStruct struct {
	foo int
}

func main() {

	var ms *myStruct
	//ms = &myStruct{foo: 1}
	fmt.Println(ms)
	ms = new(myStruct)
	ms.foo = 42
	fmt.Println(ms.foo)

	// a := [3]int{1, 2, 3}
	// b := &a[0]
	// c := &a[1]
	// fmt.Println(a, b, c)

	//a := 42
	//b := &a
	// var a int = 42
	// var b *int = &a
	// //reference. dereference
	// a = 27
	// *b = 14
	// fmt.Println(a, *b)

}

Creating pointers

        Pointer types use an asterisk(*) as a prefer to type pointed  to

                *int - a pointer to an integer

        Use the addressof operator (&) to get address of variable

Deferencing pointers

        Deference a pointer by putting an asterisk to the pointer

        Complex types automatically deference the pointer

Create pointers to objects

        can use the addressof operator if value type already exists

        use addressof operator before initializer

                &myStruct{foo:43}

        use the new keyword

                can not initialize fields at the same time

Types with internal pointers

        all assignment opetations in Go are copy opearatiosn

        alices and maps are using pointers to copy

package main

import (
	"fmt"
)

func sayGreeting(greeting, name string) {
	fmt.Println(greeting, name)
	name = "ted"
	fmt.Println(name)
}

func sayGreeting1(greeting, name *string) {
	fmt.Println(*greeting, *name)
	*name = "ted"
	fmt.Println(*name)
}

func sum(values ...int) int {
	fmt.Println(values)
	result := 0
	for _, v := range values {
		result += v
	}
	return result
}

func sum1(msg string, values ...int) {
	fmt.Println(values)
	result := 0
	for _, v := range values {
		result += v
	}

	fmt.Println(msg, result)
}

func sum2(msg string, values ...int) *int {
	fmt.Println(values)
	result := 0
	for _, v := range values {
		result += v
	}

	fmt.Println(msg, result)
	return &result
}

func divide(a, b float64) (float64, error) {
	if b == 0.0 {
		return 0.0, fmt.Errorf("can not divide by zero")
	}
	return a / b, nil
}

type greeter struct {
	greeting string
	name     string
}

func (g greeter) greet() {
	fmt.Println(g.greeting, g.name)
	g.name = "dfsa"
}

func (g *greeter) greet1() {
	fmt.Println(g.greeting, g.name)
	g.name = "dfsa"
}
func main() {

	g := greeter{
		greeting: "heelo",
		name:     "john",
	}
	g.greet()
	fmt.Println(g.name)
	g.greet1()
	fmt.Println(g.name)

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

	// for i := 0; i < 5; i++ {
	// 	func(i int) {
	// 		fmt.Println(i)
	// 	}(i)
	// }

	// func() {
	// 	fmt.Println("hello")
	// }()

	// d, err := divide(3.12, 0)
	// if err != nil {
	// 	fmt.Println(err)
	// 	return
	// }
	// fmt.Println(d)

	// sumRes2 := sum2("the reuslt is", 1, 2, 3)
	// fmt.Println("the sum is ", *sumRes2)

	// sumRes := sum(1, 2, 3, 4)
	// fmt.Println(sumRes)

	// sum1("the result is ", 1, 2, 3)

	// greeeting := "heelo"
	// name := "stacy"
	// sayGreeting(greeeting, name)
	// fmt.Println(name)
	// sayGreeting1(&greeeting, &name)
	// fmt.Println(name)

}

Function

basic syntax

Parameters

        Comma delimited list of variables and types

        parameters of same type list type once

        when pointers are passed in, the function can change the value in the caller

                this is always true for slices and maps

        use variadic parameters to send list of same types in

                must be last parameter

                receive as a slice

     

return values

        single return values just list type

        multiple return values list types surrounded by parentheses

        can return addresses of local variables

                automatically promote from the local stack

        function as a variable just like int, or slice

       

Method

        function that executes in context of a type

        Receiver can be value or pointer 

Interface

        BAsics

        Composing interfaces

        Type Conversion

Implementing with values vs pointers

Best practices

package main

import (
	"fmt"
	"runtime"
	"sync"
)

var wg = sync.WaitGroup{}
var counter = 0
var m = sync.RWMutex{}

func sayHello() {

	fmt.Println("Hello ", counter)
	m.RUnlock()
	wg.Done()
}

func increment() {

	counter++
	m.Unlock()
	wg.Done()
}

func main() {
	//runtime.GOMAXPROCS(100)
	threadsNUm := runtime.GOMAXPROCS(-1)
	fmt.Println(threadsNUm)

	// for i := 0; i < 10; i++ {
	// 	wg.Add(2)
	// 	m.RLock()
	// 	go sayHello()
	// 	m.Lock()
	// 	go increment()
	// }
	// wg.Wait()

	// var msg = "hello"
	// wg.Add(1)
	// go func(msg string) {
	// 	fmt.Println(msg)
	// 	wg.Done()
	// }(msg)
	// msg = "dfad"
	// wg.Wait()
	// //time.Sleep(100 * time.Millisecond)
	// fmt.Println("main go routine finished")

}

Donot create goroutines in libraries

        let consumer control concurrency

when creating a goroutine, know how it will end

        avoids subtle memory leaks

check for race conditions at compile time

Creating goroutine

        Use go keywod

        when using anomyous, pass the parameter as local variable

Synchronization

        waitGroup to wait for groups of goroutines to complete

        Mutex RWMutext to sync 

       

Parallelism

        by default, Go will use CPU threads equal to available cores

        Change with runtime.GOMAXPROCS

        More threads can increase performance, but too many can slow it down

        

Channel basics

restricting data flow

buffered channels

closing channels

for ... range loops with channels

select statement


func main() {
	

	// s := []int{3, 4, -2, 5, 6}
	// c := make(chan int)
	// go sum(s[:len(s)/2], c)
	// go sum(s[len(s)/2:], c)
	// x, y := <-c, <-c
	// fmt.Println(x, y, x+y)

	// ch := make(chan int, 2)
	// ch <- 1
	// ch <- 2

	// fmt.Println(<-ch, <-ch)

	c := make(chan int, 10)
	go fibonaci(cap(c), c)

	for i := range c {
		fmt.Println(i)
	}

}

func fibonaci(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 sum(s []int, c chan int) {
	sum := 0
	for _, v := range s {
		sum += v
	}
	c <- sum
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值