GO学习笔记 | 第一章节 GO语言基础| 1.环境安装 hello_word 基础数据类型 变量与常量 运算符

GO学习笔记 | 第一章节 GO语言基础| 1.环境安装 hello_word 基础数据类型 变量与常量 运算符

常用快捷键

1.ctrl+鼠标左键,可以直接进入这个函数,也就是 跳转到函数/变量定义处

2.Alt + ← = 后退(回到上一个光标位置)

3.Alt + → = 前进(去到下一个光标位置)

使用场景:

复制代码
1. 你在 main.go 的第 10 行
2. 按住 Ctrl 点击 Func1,跳转到了 utils.go 的第 50 行
3. 按住 Ctrl 点击 Func2,跳转到了 helper.go 的第 30 行
4. 按 Alt + ← 就回到了utils.go 的第 50 行
5. 再按 Alt + ← 回到 main.go 的第 10 行
6. 按 Alt + → 前进到 utils.go 的第 50 行

文章目录

一、Go开发环境搭建

具体内容可以看上篇博客,这里并没有配置图片

1.1 安装Go

  • 下载地址:使用镜像站下载
  • 版本选择:安装最新版本(建议1.18+,因为要使用泛型特性)
  • 芯片选择
    • macOS:确认是Apple芯片还是Intel芯片
    • Linux/Windows:直接选择对应版本

1.2 环境变量配置

macOS/Linux (bash/zsh)

~/.zshrc~/.bashrc 中配置:

bash 复制代码
# Go安装路径
export GOROOT=/usr/local/go

# Go项目存放路径
export GOPATH=$HOME/go

# 将Go命令加入PATH
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

# 国内代理(推荐配置)
export GOPROXY=https://goproxy.cn,direct

# 私有库配置(如需要)
# export GOPRIVATE=gitlab.yourcompany.com
Windows

通过系统设置 → 环境变量:

  • 新建 GOROOT:指向Go安装目录(默认 C:\Program Files\Go
  • 新建 GOPATH:项目存放路径
  • 编辑 Path:添加 %GOROOT%\bin%GOPATH%\bin

1.3 验证安装

bash 复制代码
go version
go env

1.4 IDE推荐

强烈推荐使用 GoLand(JetBrains出品)

  • 对新手友好,开箱即用
  • 自动代码补全、格式化
  • 调试功能强大

配置要点

  1. 设置Go SDK路径
  2. 启用Go Modules
  3. 配置GOPROXY代理

二、第一个Go程序

2.1 项目初始化

bash 复制代码
# 创建项目目录
mkdir hello-go
cd hello-go

# 初始化Go模块
go mod init github.com/yourname/hello-go

2.2 编写main.go

go 复制代码
package main

import "fmt"

func main() {
    fmt.Println("Hello, Go!")
}

2.3 关键概念

package声明
  • package main:表示这是一个可执行程序
  • 必须在main包中才能运行
  • 其他包名用于库代码
main函数
  • 程序入口点
  • 无参数、无返回值
  • 必须在main包中

推荐写法是一个目录下就只写一个main函数

2.4 运行程序

使用vscode通过命令行进行运行的话:

bash 复制代码
# 方式1:直接运行
go run main.go

# 方式2:编译后运行
go build -o hello-go
./hello-go

# 方式3:编译当前目录所有文件
go run .

如果是golang的话直接运行就是了

2.5 常见错误

错误1package command line argument is not a main package

  • 原因:package名不是main
  • 解决:将package xxx改为package main

错误2undefined: xxx

  • 原因:引用了其他文件的函数但没有一起编译
  • 解决:go run .go run main.go other.go

三、基本数据类型

3.1 整数类型

类型 大小 说明
int 4或8字节 默认整数类型,根据系统决定
int8 1字节 -128 ~ 127
int16 2字节 -32768 ~ 32767
int32 4字节 约-21亿 ~ 21亿
int64 8字节 很大范围
uint 4或8字节 无符号整数(非负)
uint8 1字节 0 ~ 255
uint16 2字节 0 ~ 65535
uint32 4字节 0 ~ 约42亿
uint64 8字节 很大范围
uintptr 取决于系统 用于存储指针地址

使用建议

  • 遇事不决用 intuint
  • 需要与其他系统交互时(如序列化),明确指定字节数
  • 现代计算机不差那点内存,优先使用64位

3.2 浮点数类型

类型 大小 说明
float32 4字节 单精度浮点数
float64 8字节 双精度浮点数(推荐)

使用建议

  • 优先使用 float64
  • 现代计算机不差那点内存

3.3 布尔类型

go 复制代码
var flag bool = true  // 或 false

问题1:!(a && b) 等价于什么?

答案:!a || !b

复制代码
!(a && b) ≡ !a || !b

理解

  • "非(a 且 b)" = "非a 或 非b"
  • 举例:不是(有钱又帅)= 没钱 或者 不帅

问题2:!(a || b) 等价于什么?

答案:!a && !b

复制代码
!(a || b) ≡ !a && !b

理解

  • "非(a 或 b)" = "非a 且 非b"
  • 举例:不是(有钱或帅)= 没钱 并且 不帅

3.4 字符串类型

两种定义方式
go 复制代码
// 方式1:双引号(单行)
str1 := "Hello, Go!"

// 方式2:反引号(支持多行,不转义)
str2 := `Hello,
World!
这是多行字符串`
字符串操作
go 复制代码
package main

import (
    "fmt"
    "strings"
    "unicode/utf8"
)

func main() {
    str := "Hello, 世界"
    
    // 字符串拼接
    newStr := str + "!"
    
    // 长度(字节数)- 注意:中文字符会占多个字节
    byteLen := len(str)  // 13(英文1字节,中文3字节)
    
    // 字符数量(正确统计中文)
    charCount := utf8.RuneCountInString(str)  // 9
    
    // 常用strings包方法
    strings.HasPrefix(str, "Hello")  // true
    strings.HasSuffix(str, "世界")   // true
    strings.Contains(str, "llo")     // true
    strings.Split(str, ", ")         // ["Hello", "世界"]
}

⚠️ 重要提醒

  • len() 返回的是字节数,不是字符数
  • 统计中文字符数要用 utf8.RuneCountInString()
  • Go默认使用UTF-8编码

3.5 字节类型

go 复制代码
// byte 是 uint8 的别名
type byte = uint8

// 字符串与字节切片转换
str := "hello"
bytes := []byte(str)    // 字符串转字节切片
str2 := string(bytes)   // 字节切片转字符串

四、变量与常量

4.1 变量声明

方式1:完整声明

var + 变量名 + 类型

go 复制代码
var a int = 10
var b int64 = 100
方式2:类型推断
go 复制代码
var c = 20        // 自动推断为int
var d = "hello"   // 自动推断为string
方式3:简短声明(仅局部变量)
go 复制代码
e := 30           // 只能在函数内部使用
f := 3.14         // 自动推断为float64
方式4:批量声明
go 复制代码
var (
    x = 1
    y = 2
    z = "hello"
)

4.2 变量作用域

go 复制代码
package main

// 包级变量(包内所有文件可访问)
var GlobalVar = 100

// 包内私有变量(小写开头)
var internalVar = 200

func main() {
    // 局部变量(仅在main函数内有效)
    localVar := 300
    
    // 使用变量
    println(GlobalVar, internalVar, localVar)
}

其实是不是包私有的就看你在函数外面定义的那个变量开头是大写还是小写,小写就私有,大写就共有

命名规范

  • 使用驼峰命名(如:userNametotalCount
  • 首字母大写:包外可访问(导出)
  • 首字母小写:包内私有

⚠️ 老师建议:尽量避免使用包级变量,使用依赖注入替代

注:如果main函数外面有个全局变量aa,里面有个自己的局部变量aa,那么main调用的时候只能用自己的aa,这种问题尽量避免吧

4.3 常量声明

4.4 常量声明:iota枚举

iota 是Go的常量计数器,从0开始,每行自动+1

go 复制代码
//默认是+1
const (
    StatusInit = iota     // 0
    StatusRunning         // 1
    StatusPaused          // 2
    StatusStopped         // 3
)

// 更复杂的用法 让他自增的方式改变了
const (
    FlagA = 1 << iota     // 1 (二进制: 001)
    FlagB                 // 2 (二进制: 010)
    FlagC                 // 4 (二进制: 100)
)

// 中断iota 重新写个const()的话iota还是从0开始的,而不是已经计数过的3或者100
const (
    StateA = iota         // 0
    StateB = 100          // 100
    StateC                // 100(保持上一个值)
    StateD = iota         // 3(恢复计数)
)

五、运算符

5.1 算术运算符

go 复制代码
a, b := 10, 3

sum := a + b      // 13
diff := a - b     // 7
product := a * b  // 30
quotient := a / b // 3(整数除法)
remainder := a % b // 1(取余)

⚠️ 注意事项

  • 除零会导致panic(程序崩溃)
  • 不同类型不能直接运算,需要显式转换,甚至int和int32都不能直接进行运算

5.2 类型转换

go里面比较严格,不存在自动类型转换,只有显示转换才行,如果你不进行转换,那就只能等着报错了

go 复制代码
var a int = 10
var b float64 = 3.14

// 错误:不同类型不能直接运算
// c := a + b  // 编译错误

// 正确:显式转换
c := float64(a) + b   // 13.14
d := a + int(b)       // 13(会丢失小数部分)

5.3 数学运算包

5.4 逻辑运算符

go 复制代码
a, b := true, false

a && b  // 与: false
a || b  // 或: true
!a      // 非: false

问题1:!(a && b) 等价于什么?

答案:!a || !b

复制代码
!(a && b) ≡ !a || !b

理解

  • "非(a 且 b)" = "非a 或 非b"
  • 举例:不是(有钱又帅)= 没钱 或者 不帅

问题2:!(a || b) 等价于什么?

答案:!a && !b

复制代码
!(a || b) ≡ !a && !b

理解

  • "非(a 或 b)" = "非a 且 非b"
  • 举例:不是(有钱或帅)= 没钱 并且 不帅

六、重要注意事项

6.1 代码格式化

Go有内置的代码格式化工具,IDE保存时会自动格式化:

bash 复制代码
go fmt main.go  # 格式化单个文件
go fmt ./...    # 格式化整个项目

6.2 未使用变量

Go是严格的,声明但未使用的变量会导致编译错误:

go 复制代码
func main() {
    a := 10
    // 如果不使用a,编译会报错:a declared and not used
    println(a)  // 使用了就不会报错
}

6.3 同名变量遮蔽

go 复制代码
func main() {
    a := 10
    {
        a := 20  // 这是新的变量,遮蔽了外部的a
        println(a)  // 20
    }
    println(a)  // 10(外部的a)
}

IDE会用绿色高亮警告变量遮蔽,建议避免这种写法