【Go】1、Go语言基础

前言

本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。


Go语言的特点

Go语言由Google团队设计,以简洁、高效、并发友好为核心目标。

具有以下优点:

  1. 语法简单、 学习曲线 平缓:语法关键字很少,且容易记忆。

  2. 丰富的 标准库:大多数情况下不需要外部引入第三方库,直接使用内置标准库即可。

  3. 完善的工具链:包管理、代码格式化、测试、性能分析、文档生成、依赖管理等等,应有尽有。

  4. 静态链接:部署简单,跨平台性强,安全稳定。

  5. 高性能、高并发:接近c的性能,低内存开销。

下文将介绍Go语言的基本语法,个人感觉更是Go语言现代化(甚至有点超现代化)的体现。


数据类型

Go语言常用的数据类型:

|--------|----------------------|-----------------------------------------------|---------|----------------------------|
| 类型分类 | 类型名称 | 关键字/定义 | 默认值(零值) | 特点 |
| 布尔型 | bool | bool | false | 只能为 true 或 false |
| 整数型 | 有符号整数 | int, int8, int16, int32, int64 | 0 | 根据平台不同,int 可能为 32 或 64 位 |
| | 无符号整数 | uint, uint8, uint16, uint32, uint64 | 0 | 无负数范围 |
| 浮点型 | float32, float64 | float32, float64 | 0.0 | float64 精度更高 |
| 字符/字节型 | byte(别名) | byte | 0 | uint8 的别名 |
| | rune(别名) | rune | 0 | int32 的别名 |
| 字符串型 | string | string | "" | 不可变,UTF-8 编码 |
| 错误类型 | error | error | nil | 内置接口类型,表示错误状态 |


一、变量定义

Go语言的变量定义方式有很多种:

  1. var name type :用于显式定义变量。
Go 复制代码
var a, b int = 1, 2
  1. name := val :用于隐式定义变量。
Go 复制代码
f := float32(e)
  1. const name type = val : 用于常量定义
Go 复制代码
const s string = "constant"

二、选择结构

选择结构分为 if ,switch-case。

  1. if
Go 复制代码
if a == 1 {
    fmt.Println("真的")
}else {
    fmt.Println("假的")
}
  1. switch-case
Go 复制代码
a := 2
switch a {
case 1:
    fmt.Println(1)
case 2:
    fmt.Println(2)
default:
    fmt.Println("default")
}

三、循环结构

Go语言形式上只有for循环一种循环方式,但是可以改为类似于while的形式循环。

Go 复制代码
for i := 1; i < 9; i++ {
    fmt.Print(i)
}
k := 1
for k < 10 {
    k++
    fmt.Println(k)
}

四、数组

Go语言的数组和C很类似,定长数组。

Go 复制代码
for i := 1; i < 9; i++ {
    fmt.Print(i)
}
k := 1
for k < 10 {
    k++
    fmt.Println(k)
}

五、切片

Go语言的切片类似于C++的vector、Java中的List,是一种变长数组。

并且支持类似Python中元组的操作语法。

Go 复制代码
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println(s[2])
fmt.Println(len(s))
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s)
c := make([]string, len(s))
copy(c, s)
fmt.Println(c)
fmt.Println(s[2:5])
fmt.Println(s[:4])
fmt.Println(s[2:])
good := []string{"g", "h", "o"}    
fmt.Println(good)

六、Map

和各种语言的Map类似,用于存储键值对。

Go 复制代码
mp := make(map[string]int)
mp["one"] = 1
mp["two"] = 2
r, ok := mp["unknow"]
fmt.Println(r, ok)

七、range

Go语言中的range类似于C++的auto,用于快速遍历。

Go 复制代码
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
        sum += num
        if num == 2 {
                fmt.Println("idx:", i, "num:", num)
        }
}
fmt.Println(sum)
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
        fmt.Println(k, v)
}
for k := range m {
        fmt.Println(k)
}

八、函数

Go语言的函数,个人认为是Go语言在语法上现代化的标志之一,支持多返回,非常方便。

Go 复制代码
func add(a int, b int) (int, string) {
    return a + b, "ok"
}

九、指针

Go语言的指针类似C的指针,个人非常喜欢指针,一直觉得Java把指针完全去除了也是一个问题。

在语法上,*作为解引用、&作为引用。

Go 复制代码
func add2(a *int) {
    *a += 2
}

十、结构体

Go语言提供结构体用于类型封装,特殊的是,结构体方法在Go语言中需要写在外面。

Go 复制代码
type user struct {
    name     string
    password string
}
func (this user) checkPassword(password string) bool {
    return this.password == password
}

十一、错误处理

Go语言为函数提供了一种新奇的try-catch方法。Go语言中,我们在某种方面来讲是在面向异常编程。我们需要通过 error 类型将函数中的错误返回,然后手动处理。

Go语言提供了一个特殊变量 nil 用于判断是否捕捉到了异常。

Go 复制代码
func checkError(password string) (bool, error) {
    return password == "123", errors.New("not Found")
}
v, err := checkError("456")
if err != nil {
        fmt.Println(v, err)
} else {
        fmt.Print(v)
}

十二、特殊函数

  1. json处理
Go 复制代码
type userInfo struct {
    Name string
    Age  int `json:"age"`
}
func solve14() {
        a := userInfo{Name: "wang", Age: 18}
        buf, err := json.Marshal(a)
        if err != nil {
                panic(err)
        }
        fmt.Println(buf)
        fmt.Println(string(buf))
        var b userInfo
        err = json.Unmarshal(buf, &b)
        if err != nil {
                panic(err)
        }
        fmt.Println(b)
}
  1. 时间处理
Go 复制代码
fmt.Println(time.Now())
fmt.Println(time.Now().Unix())
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
fmt.Println(time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC))
  1. 字符串转数字
Go 复制代码
fmt.Println(strconv.ParseInt("111", 10, 64))
fmt.Println(strconv.ParseFloat("111.11", 64)
fmt.Println(strconv.ParseInt("0x1000", 0, 64
fmt.Println(strconv.Atoi("111"))
  1. 获取线程信息
Go 复制代码
fmt.Println(os.Args)
fmt.Println(os.Getenv("PATH"))

下篇将对学习的语法结合视频进行综合实践。

相关推荐
microrain2 小时前
SagooIoT 的数据接入层只有四张表,却能接住三种外部数据
物联网·golang·数据建模·sagooiot
fly-iot3 小时前
【FDE知识库】(4):企业知识库怎么选型,开源知识库分享几个,选择开源协议友好的版本,开发wiki-go项目
golang·开源·开源协议
福大大架构师每日一题5 小时前
excelize v2.11.1发布:Go 1.26.0起步,16项安全修复与嵌入对象能力全面升级
开发语言·安全·golang
小小龙学IT7 小时前
Go 语言 pprof 性能剖析与调优深度解析:把“卡在哪“变成一张可执行的数据图
开发语言·后端·golang
十二同学啊8 小时前
Go 工程化详解:项目结构、代码规范、测试体系与 CI/CD 实践
ci/cd·golang·代码规范
利威尔xu18 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
利威尔xu19 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
FungLeo20 小时前
成为全栈·Go 后端篇·从 Node SQLite 到 PostgreSQL:把迁移做成独立交付物
postgresql·golang·sqlite·go·数据库迁移·成为全栈
皓月盈江1 天前
GO使用Gin框架实现模板定义、解析与渲染
linux·golang·go·gin·定义模板·解析模板·渲染模板
利威尔xu1 天前
万字详解|Go 进阶(五):sync 包底层:Mutex 自旋 4 次转饥饿,WaitGroup 漏 1 个 Done 挂起 3000 goroutine
后端·golang·并发编程·源码分析·sync