学习笔记8小时转职Golang工程师(如果你想低成本学习Go语言)
常用操作 1 2 3 echo $GOPATH go run <filename.go> go build <filename.go>
Go的格式化占位符 以下是Go语言中的全部格式化占位符:
通用占位符:
%v
:根据值的类型选择合适的格式化方式。
%+v
:与%v
类似,但在结构体中包含字段名。
%#v
:使用Go语法表示值。
%T
:打印值的类型。
整数:
%b
:二进制表示。
%c
:对应的Unicode字符。
%d
:十进制表示。
%o
:八进制表示。
%O
:带0o前缀的八进制表示。
%q
:带引号的字符。
%x
:小写字母的十六进制表示。
%X
:大写字母的十六进制表示。
浮点数与复数:
%b
:无小数部分的二进制指数表示。
%e
:科学计数法表示的小写字母’e’。
%E
:科学计数法表示的大写字母’E’。
%f
:默认的浮点数格式。
%F
:等同于%f
。
%g
:根据实际情况选择%e
或%f
格式化浮点数。
%G
:根据实际情况选择%E
或%f
格式化浮点数。
字符串与字节切片:
%s
:直接输出字符串或字节切片。
%q
:带引号的字符串或字节切片。
%x
:十六进制,小写字母,两个字符表示一个字节。
%X
:十六进制,大写字母,两个字符表示一个字节。
指针:
布尔值:
宽度与精度:
%b
:宽度为二进制位数。
%d
:宽度为十进制数位数。
%o
:宽度为八进制数位数。
%x
:宽度为十六进制数位数。
%f
:精度为默认的小数点后6位。
%e
:精度为默认的小数点后6位。
%g
:精度为默认的小数点后6位。
%s
:宽度为输出的字符数。
其他:
这些格式化占位符涵盖了Go语言中常用的数据类型和格式化需求。根据具体情况,选择适合的占位符来格式化输出。
Golang的优势 简单的部署方式 可以直接编译成机器码 不依赖其他库 直接运行即可部署
静态类型语言 编译的时候可以检查出来隐藏的大多数问题
语言层面的并发 天生支持并发 充分利用多核
强大的标准库 runtime系统调度机制 高效的GC垃圾回收 丰富的标准库
Golang适合用来做什么项目 云计算基础设施领域 Docker Kubernetes etcd consul cloudflare CDN 七牛云存储
代表作 docker k8s
Golang的劣势 包管理不完善 所有的Excepition都用Error来处理,没有try catch语法 配置环境变量 1 2 3 4 export GOROOT="/usr/local/go" export GOPATH="/Users/sentient3326/GOPATH" export PATH="$PATH :$GOROOT /bin:GOPATH/bin"
Hello World 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package main import "fmt" import ( "fmt" "time" "math" ) func main () { fmt.Println("hello GO" ) }
Go语言的变量声明 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package mainimport "fmt" func main () { var a int fmt.Println("a =" , a) var b int = 100 fmt.Println("b = " , b) var c = 1000 fmt.Println("c = " , c) fmt.Printf("type of c = %T\n" , c) e := 100 fmt.Printf("type of e = %T\n" , e) var x, y int = 100 , 200 fmt.Println("x =" , x, "y =" , y) var X, Y = "yihaX" , 9.9 fmt.Println("X =" , X, "Y =" , Y) var ( v1 int = 100 v2 = "wuhu" ) fmt.Println("v1 = " , v1, "v2 = " , v2) }
Const和iota 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package mainimport "fmt" const ( int1 = iota + 1 int2 int3 int4 ) const ( a, b = iota + 1 , iota + 2 c, d e, f g, h = iota * 2 , iota * 3 i, k ) func main () { const length = 10 fmt.Println("length =" , length, "int1 =" , int1, "int2 =" , int2, "int3 =" , int3, "int4 =" , int4) fmt.Println("a = " , a, "b = " , b) fmt.Println("c = " , c, "d = " , d) fmt.Println("e = " , e, "f = " , f) fmt.Println("g = " , g, "h = " , h) fmt.Println("i = " , i, "k = " , k) }
函数的多个返回值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package mainimport "fmt" func func1 (a string , b int ) int { fmt.Println("a =" , a) fmt.Println("b =" , b) c := 100 return c } func func2 () (int , string ) { return 1 , "yiha" } func func3 () (ret1 int , ret2 string ) { return ret1, ret2 } func func4 () (ret1, ret2 int ) { return ret1, ret2 } func main () { fmt.Println(func1("yiha" , 10 )) fmt.Println(func2()) fmt.Println(func3()) fmt.Println(func4()) }
init函数与import导包
1 2 3 4 5 6 7 8 9 10 11 12 package mainimport ( "GolangStudy/05init/lib1" "fmt" ) func main () { fmt.Println("this is main" ) lib1.Silent() }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package lib1import ( "GolangStudy/05init/lib2" "fmt" ) func Silent () {} func init () { fmt.Println("running lib1" ) lib2.Silent() }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 package lib2import "fmt" func Silent () {} func init () { fmt.Println("running lib2" ) } ── 05i nit ├── lib1 │ └── lib1.go ├── lib2 │ └── lib2.go └── main.go
匿名导包,别名导包,dot导包 1 2 3 4 5 6 7 import ( "GolangStudy/05init/lib1" _ "GolangStudy/05init/lib3" AnotherName "GolangStudy/05init/lib4" . "GolangStudy/05init/lib5" "fmt" )
指针 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package mainimport "fmt" func main () { a := 10 b := 20 swap(&a, &b) fmt.Println("a =" , a, "b = " , b) c := 99 pc := &c var ppc **int = &pc fmt.Println("&c =" , &c, "pc =" , pc, "&pc =" , &pc, "ppc =" , ppc, "&ppc =" , &ppc) fmt.Println("**ppc = " , **ppc) } func swap (pa, pb *int ) { t := 0 t = *pa *pa = *pb *pb = t }
defer 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package mainimport "fmt" func main () { deferAndReturn() } func deferFunc () { fmt.Println("deferFunc" ) } func returnFunc () int { fmt.Println("returnFunc" ) return 0 } func deferAndReturn () int { defer deferFunc() return returnFunc() }
动态数组 数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package mainimport "fmt" func printArr (arr []int ) { fmt.Println("in func address =" , &arr[0 ]) for _, value := range arr { fmt.Println("value =" , value) } } func main () { var Array1 [10 ]int for i := 0 ; i < len (Array1); i++ { fmt.Println(Array1[i]) } Array2 := [10 ]int {1 , 2 , 3 , 4 } for i, j := range Array2 { fmt.Println("index =" , i, "value =" , j) } sliceArr := []int {1 , 2 , 3 , 4 } for i, j := range sliceArr { fmt.Println("index =" , i, "value =" , j) } printArr(sliceArr) fmt.Println("in main address =" , &sliceArr[0 ]) }
slice切片的追加与截取 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package mainimport "fmt" func sliceAppend () { number := make ([]int , 3 , 5 ) fmt.Printf("len = %d,cap = %d,slice = %v\n" , len (number), cap (number), number) number = append (number, 9 ) fmt.Printf("len = %d,cap = %d,slice = %v\n" , len (number), cap (number), number) number = append (number, 9 , 9 ) fmt.Printf("len = %d,cap = %d,slice = %v\n" , len (number), cap (number), number) slice := make ([]int , 1 ) fmt.Printf("len = %d,cap = %d,slice = %v\n" , len (slice), cap (slice), slice) } func sliceCut () { slice := []int {1 , 2 , 3 } s1 := slice[0 :2 ] fmt.Println(s1) s2 := make ([]int , 3 ) copy (s2, slice) fmt.Println(s2) } func main () { sliceAppend() sliceCut() }
map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 package mainimport "fmt" func map1 () { var map1 map [string ]string map1 = make (map [string ]string , 3 ) map1["first" ] = "1" map1["second" ] = "2" map1["third" ] = "3" fmt.Println(map1) map2 := make (map [string ]string ) fmt.Println(map2) map3 := map [string ]string { "key1" : "value1" , "key2" : "value2" , "key3" : "value3" , } fmt.Println(map3) } func printMap (map1 map [string ]string ) { for key, value := range map1 { fmt.Println("key =" , key, "value =" , value) } } func useMap () { map1 := map [string ]string { "key1" : "value1" , "key2" : "value2" , "key3" : "value3" , } map1["key4" ] = "value4" printMap(map1) delete (map1, "key1" ) } func main () { useMap() map1() }
结构体与面向对象 封装与表示 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package mainimport "fmt" type Book struct { title string auth string } func func1 () { var b1 Book b1.title = "Golang" b1.auth = "zuozhe" fmt.Println(b1) } type Person struct { name string weight int height float32 } func (p Person) getName () { fmt.Println("Name =" , p.name) } func (p *Person) setName (name string ) { p.name = name } func main () { var p1 Person p1.name = "Makima" p1.weight = 55 p1.height = 168 p1.setName("MakimaBiss" ) p1.getName() }
继承 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 package mainimport "fmt" type Human struct { name string gender string } func (p Human) getName () string { return p.name } func (p *Human) setName (name string ) { p.name = name } type SuperMan struct { Human level int skill string } func (s1 SuperMan) Show () { fmt.Println("name =" , s1.name, "gender =" , s1.gender, "level =" , s1.level, "skill = " , s1.skill) } func (s1 SuperMan) getName () { fmt.Println("this is a rewrite method" ) } func main () { var h1 Human h1.name = "makima" h1.gender = "F" h1.name = h1.getName() h1.setName("makima" ) fmt.Println(h1) var s1 SuperMan s1.name = "superman" s1.gender = "M" s1.level = 10 s1.skill = "wuhu" s1.Show() s1.getName() s1.setName("Dyan" ) s1.Show() }
Go语言中多态的实现 多态的基本要素:1.有一个父类(接口)2.有子类(实现了父类的全部接口方法) 3.父类类型的变量(指针)指向子类的具体数据变量 对外暴露父类方法,实际调用子类方法 接口的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package mainimport "fmt" type Animal interface { Sleep() GetColor() string GetType() string } type Cat struct { color string } func (cat Cat) Sleep () { fmt.Println("Cat is Sleep" ) } func (cat Cat) GetColor () string { return cat.color } func (cat Cat) GetType () string { return "Cat" } type Dog struct { color string } func (dog Dog) Sleep () { fmt.Println("Dog is Sleep" ) } func (dog Dog) GetColor () string { return dog.color } func (dog Dog) GetType () string { return "Dog" } func main () { var animal Animal = &Cat{"White" } animal.Sleep() animal = &Dog{"black" } animal.Sleep() }
万能类型 空接口interface{}和“断言机制”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package mainimport "fmt" type Cat struct { name string } func Func1 (arg interface {}) { fmt.Printf("type of arg is %T" , arg) _, flag := arg.(string ) if flag { fmt.Println("arg is string type " ) } else { fmt.Println("arg is not string type " ) } } func main () { cat := Cat{"mimi" } Func1(cat) }
反射 变量内置pair结构
反射机制的用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 package mainimport ( "fmt" "reflect" ) type User struct { id int name string salary float32 } func (user User) Call () { fmt.Println("User is Called" ) fmt.Printf("%v\n" , user) } func reflectNum (arg interface {}) { fmt.Println("type = " , reflect.TypeOf(arg)) fmt.Println("value = " , reflect.ValueOf(arg)) } func reflectStruct (arg interface {}) { argType := reflect.TypeOf(arg) argValue := reflect.ValueOf(arg) for i := 0 ; i < argType.NumField(); i++ { field := argType.Field(i) value := argValue.Field(i) fmt.Printf("type of %s is %v value = %v\n" , field.Name, field.Type, value) } for i := 0 ; i < argType.NumMethod(); i++ { m := argType.Method(i) fmt.Printf("%s:%v" , m.Name, m.Type) } } func main () { var num float32 = 1.2345 reflectNum(num) user := User{1 , "makima" , 0.0005 } reflectStruct(user) }
结构体标签 使用反射解析结构体标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package mainimport ( "fmt" "reflect" ) type resume struct { Name string `info:"name"` Age int `info:"age" extra:"tag"` } func findTag (str interface {}) { t := reflect.TypeOf(str).Elem() for i := 0 ; i < t.NumField(); i++ { properties := t.Field(i).Name infoTag := t.Field(i).Tag.Get("info" ) extraTag := t.Field(i).Tag.Get("extra" ) fmt.Println("properties:" , properties, "info:" , infoTag, "extraTag:" , extraTag) } } func main () { var r resume findTag(&r) }
结构体标签在json中的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package mainimport ( "encoding/json" "fmt" ) type Movie struct { Title string `json:"title"` Year int `json:"year"` Price int `json:"rmb"` Actors []string `json:"actors"` } func main () { movie := Movie{"电影名" , 2000 , 20 , []string {"yiha" , "makima" }} jsonStr, err := json.Marshal(movie) if err != nil { fmt.Println("json marshal error" ) return } fmt.Printf("jsonStr = %s\n" , jsonStr) movieDecode := Movie{} err = json.Unmarshal(jsonStr, &movieDecode) if err != nil { fmt.Println("json unmarshal error" ) return } fmt.Printf("Decode result is %v\n" , movieDecode) }
groutine基本模型和调度设计策略