Go语言中,你是否已熟练运用init、路径、输出、切片、Map这五大知识点?
- 内容介绍
- 文章标签
- 相关推荐
在Go语言的开发旅程中,很多人会在一些看似简单却暗藏玄机的知识点上遇到困惑。你是否曾经在程序启动顺序上摸不着头脑?或者在处理文件路径时主要原因是go run和编译后的二进制文件行为不一致而抓狂?又或者是对切片的扩容机制一知半解,导致性能瓶颈?今天我们就来聊聊Go语言中五个非常核心且高频使用的知识点:init函数、 路径处理、格式化输出、切片以及Map。这五个点,不仅是面试官的宠儿,更是写出健壮、高效Go代码的基石。
一、 init 函数:程序启动的幕后英雄
每一个Go程序的入口都是main函数,这大家都知道。但在main施行之前,其实发生了很多事情。这就是init函数的舞台。它没有参数,也没有返回值,甚至你不能在代码中显式地调用它,它由Go运行时自动管理,没耳听。。
1. init 函数施行顺序
物超所值。 每个包中可以有多个init函数,它们在同一个文件内按照从上到下的顺序施行。如果同一个包有多个文件,则按照文件名的字典序施行。这里有一个深度优先的依赖原则。比如 如果main包导入了pkgA而pkgA又导入了pkgB那么初始化的顺序一定是:先初始化pkgB然后是pkgA再说说才是main。这就像搭积木,必须先搭底下的,才能搭上面的。
包级常量初始化被处理的是常量,主要原因是它们在编译期就已经确定。 包级变量初始化接着是变量,按照声明的顺序依次进行。 init 函数施行每个包中的init main 函数施行:再说说只有所有的依赖包都初始化完毕, 入口包的mian,你看啊...
// 小切片翻倍
s1 := make // len=3, cap=4
s1 = append // 此时 len=4, cap=4
s1 = append // 此时 len=5, cap=8
// 大切片 1.25倍增长
s2 := make // len=300, cap=300
s2 = append // 触发扩容,新容量大约是 300 * 1.25 = 375
二、项目路径处理:智取根目录
package main
import (
"fmt"
"os"
"path/filepath"
)
// GetProjectRoot 能获取项目根目录
func GetProjectRoot {
// 获取当前可施行文件的绝对路径
exePath, err := os.Executable
if err != nil {
return "", err
}
// 获取可施行文件所在目录
exeDir := filepath.Dir
// 如果是 go run 模式,exe 通常在临时目录,需要向上找 go.mod
if isGoRun {
return findGoModDir
}
return exeDir, nil
}
// 判断是否是 go run 运行环境
func isGoRun bool {
// 检查参数0是否包含 "go" 或者路径在临时目录下
arg0 := filepath.Base
return arg0 == "go" || arg0 == "go.exe" || filepath.HasPrefix)
}
// 向上递归查找 go.mod
func findGoModDir {
…………
func main {
…………
}
三、格式化输出:fmt.Printf 大法好
type User struct {
Name string
Age int
}
u := User{Name: "stark张宇", Age:18}
fmt.Printf // 输出: {stark张宇 18}
fmt.Printf // 输出: {Name:stark张宇 Age:18}
fmt.Printf // 输出: main.User{Name:"stark张宇", Age:18}
fmt.Printf // 输出: main.User
…………
func main {
…………
}
四、切片的扩容策略
// 小切片翻倍
s1 := make // len=3, cap=4
s1 = append //
s1 = append//
// 大切片渐进式增长
s2 := make//len =300 ,cap =300
s2 = append//触发扩容,新容量大约375
…………
func main {
…………
}
五、Map的使用陷阱与优化
// 创建一个mapint
m := make
// 添加键值对
m = 1
// 删除键值对
delete//ok-idiom 检查键是否存在
value ,ok:= m
if ok{
FMT.Println
}else{
FMT.Println
}
// 并发读写map需加锁或使用sync.Map
var mu sync.Mutex
mu.Lock
m =3
mu.Unlock
…………
func main {
…………
}
掌握这五个知识点,不仅能帮你通过面试,更能让你在处理复杂的工程问题时游刃有余。代码写出来容易,写得好却需要不断的积累和思考。希望这篇文章能让你对这些基础概念有新的认识,写出更优雅、更高效的Go代码,物超所值。!
在Go语言的开发旅程中,很多人会在一些看似简单却暗藏玄机的知识点上遇到困惑。你是否曾经在程序启动顺序上摸不着头脑?或者在处理文件路径时主要原因是go run和编译后的二进制文件行为不一致而抓狂?又或者是对切片的扩容机制一知半解,导致性能瓶颈?今天我们就来聊聊Go语言中五个非常核心且高频使用的知识点:init函数、 路径处理、格式化输出、切片以及Map。这五个点,不仅是面试官的宠儿,更是写出健壮、高效Go代码的基石。
一、 init 函数:程序启动的幕后英雄
每一个Go程序的入口都是main函数,这大家都知道。但在main施行之前,其实发生了很多事情。这就是init函数的舞台。它没有参数,也没有返回值,甚至你不能在代码中显式地调用它,它由Go运行时自动管理,没耳听。。
1. init 函数施行顺序
物超所值。 每个包中可以有多个init函数,它们在同一个文件内按照从上到下的顺序施行。如果同一个包有多个文件,则按照文件名的字典序施行。这里有一个深度优先的依赖原则。比如 如果main包导入了pkgA而pkgA又导入了pkgB那么初始化的顺序一定是:先初始化pkgB然后是pkgA再说说才是main。这就像搭积木,必须先搭底下的,才能搭上面的。
包级常量初始化被处理的是常量,主要原因是它们在编译期就已经确定。 包级变量初始化接着是变量,按照声明的顺序依次进行。 init 函数施行每个包中的init main 函数施行:再说说只有所有的依赖包都初始化完毕, 入口包的mian,你看啊...
// 小切片翻倍
s1 := make // len=3, cap=4
s1 = append // 此时 len=4, cap=4
s1 = append // 此时 len=5, cap=8
// 大切片 1.25倍增长
s2 := make // len=300, cap=300
s2 = append // 触发扩容,新容量大约是 300 * 1.25 = 375
二、项目路径处理:智取根目录
package main
import (
"fmt"
"os"
"path/filepath"
)
// GetProjectRoot 能获取项目根目录
func GetProjectRoot {
// 获取当前可施行文件的绝对路径
exePath, err := os.Executable
if err != nil {
return "", err
}
// 获取可施行文件所在目录
exeDir := filepath.Dir
// 如果是 go run 模式,exe 通常在临时目录,需要向上找 go.mod
if isGoRun {
return findGoModDir
}
return exeDir, nil
}
// 判断是否是 go run 运行环境
func isGoRun bool {
// 检查参数0是否包含 "go" 或者路径在临时目录下
arg0 := filepath.Base
return arg0 == "go" || arg0 == "go.exe" || filepath.HasPrefix)
}
// 向上递归查找 go.mod
func findGoModDir {
…………
func main {
…………
}
三、格式化输出:fmt.Printf 大法好
type User struct {
Name string
Age int
}
u := User{Name: "stark张宇", Age:18}
fmt.Printf // 输出: {stark张宇 18}
fmt.Printf // 输出: {Name:stark张宇 Age:18}
fmt.Printf // 输出: main.User{Name:"stark张宇", Age:18}
fmt.Printf // 输出: main.User
…………
func main {
…………
}
四、切片的扩容策略
// 小切片翻倍
s1 := make // len=3, cap=4
s1 = append //
s1 = append//
// 大切片渐进式增长
s2 := make//len =300 ,cap =300
s2 = append//触发扩容,新容量大约375
…………
func main {
…………
}
五、Map的使用陷阱与优化
// 创建一个mapint
m := make
// 添加键值对
m = 1
// 删除键值对
delete//ok-idiom 检查键是否存在
value ,ok:= m
if ok{
FMT.Println
}else{
FMT.Println
}
// 并发读写map需加锁或使用sync.Map
var mu sync.Mutex
mu.Lock
m =3
mu.Unlock
…………
func main {
…………
}
掌握这五个知识点,不仅能帮你通过面试,更能让你在处理复杂的工程问题时游刃有余。代码写出来容易,写得好却需要不断的积累和思考。希望这篇文章能让你对这些基础概念有新的认识,写出更优雅、更高效的Go代码,物超所值。!

