go 基础笔记

本笔记仅为个人学习的记录,不适合想系统学习的人,仅供参考

目录

src -> 域名目录 -> 项目目录 -> 入口文件和模块

包的概念

结构体

type name struct{
    
}

引用了包,必须使用;定义了类型,必须使用

定义全局变量建议不用隐式赋值

常量不需要指定类型

批量赋值

var (
    name type = "xx"
    name2 type = ""
)

const (
    name3 = "22"
    name4 = "222"
)

定义接口

type i interface{
    
}

定义结构体

type user struct{
    name string//结构体属性
    age int
}

创建结构体

tu := user{
    name:"xxx"
    age : 1
}
或
tu := user{}
tu.name = "xx"

方法 属于结构体,根据结构体来定义的

func (u user) getAge() int {
    return u.age
}

函数

func name(){
    
}
  1. 声明在函数内部,是函数的本地值,类似private

  2. 声明在函数外部,是对当前包可见(包内所有.go文件都可见)的全局值,类似protect

  3. 声明在函数外部且首字母大写是所有包可见的全局值,类似public

注:结构体也是需要首字母大写才能被调用。结构体里的方法和属性也同样

下载第三方包

go get github.com/用户/包名

init函数 类似于构造函数

1、每个包里都可以有多个

2、加载顺序:按照引入包的顺序

类型不一样的,不能直接拿来作比较

例如

var a1 int8 = 1
var a2 int =1
a1 == a2  //会报错
需要强制转换才能作比较

常用字符串函数

len(str) 求长度

+或fmt.Sprintf() 拼接字符串

strings.Split() 分割

strings.Contains 判断是否包含

strings.HasPrefix,strings.HasSuffix 前缀/后缀判断

strings.Index(),strings.LastIndex()子串出现的位置

strings.Join(a[] string, sep string) join操作

指针

&a:取内存中的地址

*a:取内存中实际值

语法

if-else

if statement; condition {  
}

if condition {  
} else if condition {
} else {
}

switch

不需要break
fallthrough 让case往下执行
switch u{
case 表达式/值 :
case 表达式/值 :
}

for

 for i := 1; i <= 10; i++ {
        fmt.Printf(" %d",i)
    }

数组声明

var arr [3]int = [3]int{1,2,3}
//可变长度
var arr2 = [...]int{1,2,3,4}

go中,数组长度定义了就不能修改

切片

//定义
var sar []int = []int{0,2,1}

//添加元素
sar = append(sar, 10)

//初始化的时候,切片的长度和容量是一样的
len(sar)
cap(sar)

往切片里面添加元素的时候,会自动扩容,按照指数倍扩容

获取切片的部分内容

sar[index:end]

index:从哪里开始

end:截取 end-index 位元素,index必须小于end

//切片的另一种定义方式
var sar2 = make([]int, 2)

集合

//定义
map := make(map[string]string,0)
map[string]:指的是集合的key是string类型
map[string]string:指的事集合的值是string类型

map["name"] = "xiao"

同理
map2 := make(map[string][]int,0)
map3 := make(map[string][]string,0)
func TestMap(t *testing.T)  {
    map1 := make(map[string]string, 0)
    map1["name"] = "aabb"
    map1["name1"] = "aabbcc"
    fmt.Println("map1",map1)
    /***
    输出
    map1 map[name:aabb name1:aabbcc]
    **/
    
    
    //值类型 是切片
    map2 := make(map[string][]string, 0)
    s := make([]string, 0)
    s = append(s,"2","3","SS")
    map2["str1"] = s
    fmt.Println("map2",map2)
    /**
    输出
    map2 map[str1:[2 3 SS]]
    **/

    //值类型是集合的
    submap1 := make(map[string]string,0)
    submap2 := make(map[string]string,0)
    submap1["aa"] = "11"
    submap1["cc"] = "11"
    submap2["bb"] = "22"
    submap2["dd"] = "22"
    map3 := make([]map[string]string, 3)
    map3[0] = submap1
    map3[1] = submap2

    fmt.Println("map3", map3)
    /**
    输出
    map3 [map[aa:11 cc:11] map[bb:22 dd:22] map[]]
    **/
    
    //也可以先声明后赋值
    map3[2] = make(map[string]string ,0)
    map3[2]["key12"] = "aaa"

    fmt.Println("map3", map3)
    /**
    输出
    map3 [map[aa:11 cc:11] map[bb:22 dd:22] map[key12:aaa]]
    **/
}

遍历

for key, val := range map3{
        fmt.Println( key, val)
    }

死循环

for{

}

函数

不定参函数

func sum(num ...int)  {
    fmt.Println(num)
}

匿名函数

fun1 := func(k int ) {
    fmt.Println("匿名函数", k)
}

闭包

func bibao() func()  {
    i := 0
    return func() {
        i++
        fmt.Println(i)
    }
}

test := bibao()
test()

延迟执行

defer 函数名()

func def()  {
    fmt.Println("1")

    defer index()
    defer sum(1,2,3)
    fmt.Println("2")
}

def()
输出结果顺序
1
2
[1 2 3]
index 函数

异常

panic():抛出异常

recover():捕获异常

结构体2

package main

type MySplice struct {
    len int
    cap int
    arr Arr
}

type Arr struct {
    name string
}

func NewMySlice(len, cap int) *MySplice  {
    return &MySplice{
        len: len,
        cap: cap,
        arr: Arr{
            name: "nihao",
        },
    }
}

func (m *MySplice) GetLen() int {
    return m.len
}

func (a *Arr) GetName() string {
    return a.name
}

接口

package main

import "fmt"

type Pay interface {
    Order(id int) int
}

type WeChat struct {

}
type Ali struct {

}

func (wx  *WeChat) Order(id int) int  {
    return id
}

func (ali *Ali) Order(id int) int {
    return id
}

func K(pay Pay, id int)  {
    fmt.Println(pay.Order(id))
}
package main

import "testing"

//测试
func TestPay(t *testing.T)  {
    wx := &WeChat{}
    K(wx,12)
}

定义:

var k interface{}  //可以存任意类型的数据
k.(type) 可以获取类型

注册工厂案例

operation.go

package calc

type OperationInterface interface {
    operation(num1, num2 int) int
}

type Add struct {}
type Sub struct {}
type Mul struct {}
type Div struct {}

//结构体实现接口方法
func (add *Add) operation(num1 int, num2 int) int {
    return num1 + num2
}

func (sub *Sub) operation(num1 int, num2 int) int {
    return num1 + num2
}

func (mul *Mul) operation(num1 int, num2 int) int {
    return num1 + num2
}

func (div *Div) operation(num1 int, num2 int) int {
    return num1 + num2
}

oper.go

package calc

/**
全局的变量 用于存储结构体
 */
var operations map[string]OperationInterface

func init() {
    operations = make(map[string]OperationInterface,0)
    operations["+"] = &Add{}
    operations["-"] = &Sub{}
    operations["*"] = &Mul{}
    operations["/"] = &Div{}
}

func OperationExe(operation string) OperationInterface {
    return operations[operation]
}

oper_test.go

package calc

import (
    "fmt"
    "testing"
)

func TestOperation(t *testing.T) {
    num1 := 1
    num2 := 1
    operation := "+"
    fmt.Println(OperationExe(operation).operation(num1, num2))
}

使用反射

reflect.ValueOf():获取值

reflect.Value{}

reflect.ValueOf().call()

operation.go

package calc
/**
1定义接口
 */
type OperationInterface interface {
    Exe() int
}

/**
2定义公共属性结构体
 */
type Operation struct {
    num1 int
    num2 int
}

/**
3为 Operation 结构体提供访问内置属性的方法
Get 和 Set
 */
func (o *Operation) SetNum1(num int) {
    o.num1 = num
}
func (o *Operation) SetNum2(num int) {
    o.num2 = num
}
func (o *Operation) GetNum1() int {
    return o.num1
}
func (o *Operation) GetNum2() int {
    return o.num2
}

/**
4结构体伪继承 Operation 结构体
 */
type Add struct {
    oper *Operation
}
/**
Add 构造方法
 */
func NewAdd(num1, num2 int) *Add {
    return &Add{
        oper:&Operation{
            num1:num1,
            num2:num2,
        },
    }
}

type Sub struct {
    oper *Operation
}
/**
Sub 构造方法
*/
func NewSub(num1, num2 int) *Sub {
    return &Sub{
        oper:&Operation{
            num1:num1,
            num2:num2,
        },
    }
}

type Mul struct {
    oper *Operation
}
/**
Mul 构造方法
*/
func NewMul(num1, num2 int) *Mul {
    return &Mul{
        oper:&Operation{
            num1:num1,
            num2:num2,
        },
    }
}

type Div struct {
    oper *Operation
}
/**
Div 构造方法
*/
func NewDiv(num1, num2 int ) *Div {
    return &Div{
        oper:&Operation{
            num1:num1,
            num2:num2,
        },
    }
}

/**
5 实现 OperationInterface 接口的方法
 */
func (o *Add) Exe() int {
    return o.oper.num1 + o.oper.num2
}
func (o *Sub) Exe() int {
    return o.oper.num1 - o.oper.num2
}
func (o *Mul) Exe() int {
    return o.oper.num1 * o.oper.num2
}
func (o *Div) Exe() int {
    return o.oper.num1 / o.oper.num2
}

oper.go

package calc

import (
    "reflect"
)

var operations map[string]interface{}

func init() {
    operations = make(map[string]interface{}, 0)
    operations["+"] = NewAdd
    operations["-"] = NewSub
    operations["*"] = NewMul
    operations["/"] = NewDiv
}

func OperationFactory(num1, num2 int, flag string) OperationInterface {
    operation := operations[flag]
    valueOf := reflect.ValueOf(operation)
    //fmt.Println("ValueOf",valueOf)
    //fmt.Printf("ValueOf-type:%T \n",valueOf)
    args := []reflect.Value{
        reflect.ValueOf(num1),
        reflect.ValueOf(num2),
    }
    call := valueOf.Call(args)[0]
    //fmt.Println("call:", call)
    //fmt.Printf("call-type:%T \n", call)

    oper := call.Interface().(OperationInterface)
    //fmt.Println("oper:", oper)
    //fmt.Printf("oper-type:%T \n", oper)
    return oper
}

理解反射

reflect.TypeOf():获取类型 如果在函数中的参数是外界传递进来的,我们并不知道他的类型是什么,可以通过反射的的这个方法来判断他的类型

reflect.ValueOf():获取值

rv.NumField():获取结构体的字段数

rv.Field()

这里推荐一个go学习的宝藏地址
http://www.topgoer.com/

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容