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/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容