对Go语言的了解 | 青训营笔记

98 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记

一、初步认识

  • 变量
const boilingF = 212.0 //全局变量
var f = boilingF
var s1 string ="str1"
s2 := "str2"  //不能用于全局变量

//指针
x := 1
p := &x //p的数据类型是*int
  • 数组---固定长度
var a1 [3]int
var a2 [3]int{1,2,3}
for i,v :=range a2{   //for循环遍历数组
    // i-索引 v-值
}
  • Sclice--不固定长度
months := [...]string{1: "January", /* ... */, 12: "December"}
  • Map
mapList := make(map[string]int){
    "key":10,
}
//相当于
mapList := make(map[string]int)
mapList["key"] = 10
//delete函数删除元素
delete(ages, "alice") 
  • 结构体
// 采用驼峰式命名,相邻同属性成员可合并到一行
type OneStruct struct {
    ID                int
    Name,Message      string 
}
  • 函数
//支持多返回值
func name(parameter-list) (result-list) {
    //body
}

二、进一步了解——对比Java的不同

  • 错误和异常处理

在Java,错误(Error)和异常(Exception)两者差别很大。 异常是指在程序在正常运行中出现的可预料的意外情况,包括运行时异常(比如NullPointerException空指针异常)、非运行时异常(比如IOException、自定义的Exception),程序可以通过try-catch捕获等方式去处理; 而错误在程序正常的情况下一般不会出现,这时程序本身是没法处理错误的。

而在Go中只有error,一旦发生错误逐层返回,直到被处理。

if err != nil{
    //handle
}
  • Go的处理方案

    • 简单错误处理
      • 优先使用 errors.New 来创建匿名变量来直接表示该错误。有格式化需求时使用 fmt.Errorf
    • 错误的 Wrap 和 Unwrap
      • 在 fmt.Errorf 中使用 %w 关键字来将一个错误 wrap 至其错误链中
    • 错误判定
      • 使用 errors.Is 可以判定错误链上的所有错误是否含有特定的错误。
      • 在错误链上获取特定种类的错误,使用 errors.As
    • panic
      • 不建议在业务代码中使用 panic
      • 如果当前 goroutine 中所有 deferred 函数都不包含 recover 就会造成整个程序崩溃
      • 当程序启动阶段发生不可逆转的错误时,可以在 init 或 main 函数中使用 panic
    • recover
      • recover 只能在被 defer 的函数中使用,嵌套无法生效,只在当前 goroutine 生效
      • 如果需要更多的上下文信息,可以 recover 后在 log 中记录当前的调用栈。
  • 并发

    • Java 通过共享内存通信

    image.png

    • Go 提倡通过通信共享内存(CSP模型)

    image.png

  • 面向对象

Java是一门面向对象的编程语言,拥有封装、继承、多态三大特性。 而Go并不是面向对象的编程语言,没有类的概念,但可以基于结构体来实现类和类的方法的概念。它本身不支持多态,但可以通过接口特性来模拟面向对象的多态性。

  • 效率 Go被编译为机器代码并直接执行,而Java使用VM来运行代码,相比于Go更慢。

引用资料:

Go | Go和Java区别

Go 语言原理与实践 学习资料(上)

解读Java并发模型

【Golang】CSP并发模型与MPG调度模型