searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

go语言入门一

2024-01-22 03:17:49
47
0

go run 和go build的区别

  • go run 是直接出结果,go build生成可执行文件或exe
  • go run 需要go语言环境,go build不用
  • go build编译后形成的可执行文件包括依赖的库文件,体积比go run大

Byte和rune

Byte代表UTF-8的单个字节
rune代表Unicode单个字节

切片

是否和python的切片一样?(go是脚本语言、python是编译语言)

  • 不一样:
    1.python的列表和元组不限制类型,go的切片需要同类型。
    2.python的切片按参数可以为负数,go不行
    3.[a:b:c]意义不用:go的c表示容量、python的c表示步长
    4.!!python切片产生新对象,且不影响旧对象;go的切片是就对象的有部分引用,会影响
    -相同:都有[a:b]
  • make()用来创建切片、映射、通道
s2 := make([]int, 10, 20)
长度len()为10,容量cap()为20   capacity

定义数组:

a:= [...]int{1,2,3,4,5}

循环

for _,value := range a{
}

go.mod文件

  • GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找
  • go.mod 提供了module, require、replace和exclude四个命令

go mod init

JSON转换

Marshal
  • 可导出成员(变量首字母大写)
    小写不可导,不会进行转换
  • 标签

Name旁边的 json:"name" ,那么转化成的json key就用该标签“name”,否则取变量名作为key,如“Age”,“HIgh”。

type Stu struct {
    Name  string `json:"name"`
    Age   int
    HIgh  bool
    sex   string
    Class *Class `json:"class"`
}

json编码成字符串后就是纯粹的字符串了

  • interface{}:可以接受各种类型的数据
Unmarshal

第一个参数是json字符串,第二个参数是接受json解析的数据结构

protoc --go_out=. *.proto

生成gRPC对应的GoLang代码

protoc --go_out=plugins=grpc:. helloworld.proto

protobuf

作用:用于不同应用或进程通信,用protobuf定义的数据结构打包编译成二进制码流数据进行传输

安装

pip install protobuf    # 安装protobuf库
sudo apt-get install protobuf-compiler  # 安装protobuf编译器

使用

// 声明使用proto3
syntax = "proto3";

protobuf与grpc区别

grpc通过protobuf定义接口,将数据序列化成二进制码流
grpc不能直接用在生产,因为设置成分布式,需要添加负载均衡,限流熔断,监控报警,服务注册和发现

语法

  1. syntax = “proto3”;

文件的第一行指定了你使用的是proto3的语法:如果你不指定,protocol buffer 编译器就会认为你使用的是proto2的语法。这个语句必须出现在.proto文件的非空非注释的第一行。

  1. message SearchRequest {……}
  1. 字段唯一数字标识(用于在二进制格式中识别各个字段,上线后不宜再变动):Tags

1到15使用一个字节来编码,包括标识数字和字段类型(你可以在Protocol Buffer 编码中查看更多详细);16到2047占用两个字节。因此定义proto文件时应该保留1到15,用作出现最频繁的消息类型的标识。记得为将来会继续增加并可能频繁出现的元素留一点儿标识区间,也就是说,不要一下子把1—15全部用完,为将来留一点儿。

标识数字的合法范围:最小是1,最大是 229 - 1,或者536,870,911。

  1. 字段修饰符:
  • required:值不可为空
  • optional:可选字段
  • singular:符合语法规则的消息包含零个或者一个这样的字段(最多一个)
  • repeated:一个字段在合法的消息中可以重复出现一定次数(包括零次)。重复出现的值的次序将被保留。在proto3中,重复出现的值类型字段默认采用压缩编码。你可以在这里找到更多关于压缩编码的东西: Protocol Buffer Encoding。
  • 默认值: optional PhoneType type = 2 [default = HOME];
  • proto3中,省略required,optional,singular,由protoc自动选择。
  1. 代理类生成
  • C++, 每一个.proto 文件可以生成一个 .h 文件和一个 .cc 文件
  • Java, 每一个.proto文件可以生成一个 .java 文件
  • Python, 每一个.proto文件生成一个模块,其中为每一个消息类型生成一个静态的描述器,在运行时,和一个metaclass一起使用来创建必要的Python数据访问类
  • Go, 每一个.proto生成一个 .pb.go 文件
  • Ruby, 每一个.proto生成一个 .rb 文件
  • Objective-C, 每一个.proto 文件可以生成一个 pbobjc.h 和一个pbobjc.m 文件
  • C#, 每一个.proto文件可以生成一个.cs文件.
  • php, 每一个message消息体生成一个.php类文件,并在GPBMetadata目录生成一个对应包名的.php类文件,用于保存.proto的二进制元数据。
  1. 字段默认值
  • strings, 默认值是空字符串(empty string)
  • bytes, 默认值是空bytes(empty bytes)
  • bools, 默认值是false
  • numeric, 默认值是0
  • enums, 默认值是第一个枚举值(value必须为0)
  • message fields, the field is not set. Its exact value is langauge-dependent. See the generated code guide for details.
  • repeated fields,默认值为empty,通常是一个空list
  1. 枚举
  2. Maps字段类型
// 枚举类型,必须从0开始,序号可跨越。同一包下不能重名,所以加前缀来区别
enum WshExportInstStatus {
    INST_INITED = 0;
    INST_RUNNING = 1;
    INST_FINISH = 2;
    INST_FAILED = 3;
}

key_type除了floating和bytes的任意标量类型都是可以的

map<key_type, value_type> map_field = N;

$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件

go语法

  • 由于使用了:=,而不是赋值的=,因此推导声明写法的左值变量必须是没有定义过的变量。若定义过,将会发生编译错误
  • 左括号必须紧接着语句不换行
  • go get 命令获取到的库源文件下载到 src 目录下对应的文件夹当中
  • go install 命令安装某个包后的归档文件,放到pkg目录,.a文件
  • go run 命令运行或者通过go build 命令生成可执行文件
  • go build编译成二进制的可执行文件
  • ``

导入包

导入的包名使用双引号""包围,
也可以使用一个 import 关键字导入多个包,此时需要用括号( )将包的名字包围起来,并且每个包名占用一行

import(
    "name1"
    "name2"
)
  • 一个 main 包中也必须有且仅有一个 main 函数
  • 所有函数都以关键字 func 开头
func 函数名 (参数列表) (返回值列表){
    函数体
}
  • 注意:Go语言函数的左大括号{必须和函数名称在同一行,否则会报错。
  • 名称:为本条配置信息的名称,可以自定义,也可以使用系统默认的值;
  • Run kind:这里需要设置为“Directory”;
  • Directory:用来设置 main 包所在的目录,不能为空;
  • Output directory:用来设置编译后生成的可执行文件的存放目录,可以为空,为空时默认不生成可执行文件;
  • Working directory:用来设置程序的运行目录,可以与“Directory”的- 设置相同,但是不能为空。

基础语法

  • 在声明变量时将变量的类型放在变量的名称之后,小驼峰

var 变量名 变量类型

  • Go语言的基本类型有:
bool
string
int、int8、int16、int32、int64
uint、uint8、uint16、uint32、uint64、uintptr
byte // uint8 的别名
rune // int32 的别名 代表一个 Unicode 码
float32、float64
complex64、complex128

??所有的内存在 Go 中都是经过初始化的。

_是空白标识符

new():新分配类型零值的指针

GO语言变量逃逸分析

类型定义及结构体嵌入

  • 类型别名:其实还是原本那个类型
type byte = uint8  
type rune = int32
type 别名=类型,
  • 类型定义:形成一种新的类型
    type 别名 类型

容器:数组、map、字符串、通道??

注意:可以使用 make(),但不能使用 new() 来构造 map
for range 语法

Go语言make和new关键字的区别及实现原理

方法和函数的区别
方法在 func 和标识符之间多了一个参数,即接收者

//这是函数的定义
func notify(email string) {
        fmt.Println("Email is %s", email)
}

//这是方法的定义
func (u user) notify(email string) {
        fmt.Println("Email is %d", email)
}

指针接收者是可以改变属性值

  • 在一个结构体中对于每一种数据类型只能有一个匿名字段

Go 语言对 protocol buffers 和 gRPC支持

GC(垃圾回收机制)

runtime.GC()
runtime.SetFinalizer(x, f interface{}):完成一些特定的任务,例如发信号或者写日志.x 的终止器设置为 f

链表

使用结构体形成链表,单向链表、双向链表、循环链表

处理运行时错误

// 实现error接口,返回错误描述
func (e *ParseError) Error() string {
    return fmt.Sprintf("%s:%d", e.Filename, e.Line)
}

接口

  • Go语言接口的nil判断
  • Go语言的接口在命名时,一般会在单词后面添加 er
类型断言(Type Assertion)

value, ok := x.(T)
x 表示一个接口的类型,T 表示一个具体的类型(也可为接口类型)

go语言中的锁

  • 互斥锁:Mutex
  • 读写锁:RWMutex

错误和异常的区别

  • 错误基本都是可预期的,err:= func(),fmt.Errorf()
  • 异常在程序执行过程不可预期抛出的,遇到异常之后执行defer修饰的函数,输出错误信息 panic(宕机)、recover

注意:defer必须先定义,执行顺序与声明顺序相反
recover只有在defer调用的函数中有效

关于omitempty的陷阱

  • 嵌套结构体时,用指针类型才能被省略
type address struct {
    Street     string      `json:"street"`
    Ste        string      `json:"suite,omitempty"`
    City       string      `json:"city"`
    State      string      `json:"state"`
    Zipcode    string      `json:"zipcode"`
    Coordinate *coordinate `json:"coordinate,omitempty"`
}

:= 赋值操作符

只能在函数体内使用

go语言特性

并发-Goroutine

并发:交替执行,一个cpu

并行:同时执行,多个cpu

启动goroutine

go func_name()

运行时 runtime

  • func GOMAXPROCS(n int) int n<=1查询cpu核心数 n>1设置最大并行goroutine数量

同步

  • waitGroup 计数等待法 无法精确控制
    • Wait time.Sleep()
    • Done
    • Add
  • Once 执行一次
  • Mutex互斥锁 访问共享数据时就是进入临界区
    • Lock加锁 临界区一定要最小颗粒度
    • Unlock解锁
  • RWMutex 读写锁 读共享,写独享,写优先级高。
  • Cond条件变量
  • channel 通道
0条评论
0 / 1000
f****n
4文章数
1粉丝数
f****n
4 文章 | 1 粉丝