惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
O
OpenAI News
酷 壳 – CoolShell
酷 壳 – CoolShell
The GitHub Blog
The GitHub Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 聂微东
Engineering at Meta
Engineering at Meta
W
WeLiveSecurity
Hacker News: Ask HN
Hacker News: Ask HN
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
D
Docker
F
Full Disclosure
AI
AI
罗磊的独立博客
博客园 - 【当耐特】
U
Unit 42
S
SegmentFault 最新的问题
Stack Overflow Blog
Stack Overflow Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Palo Alto Networks Blog
博客园_首页
H
Help Net Security
量子位
月光博客
月光博客
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 司徒正美
F
Fortinet All Blogs
D
DataBreaches.Net
B
Blog RSS Feed
Webroot Blog
Webroot Blog
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
爱范儿
爱范儿
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
CERT Recently Published Vulnerability Notes
Martin Fowler
Martin Fowler
Blog — PlanetScale
Blog — PlanetScale
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Securelist

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次 安卓APP通话记录与录音上传踩坑记录 - 子舒的博客 天量下跌 inBox 笔记 2.3.8,把工具栏交给了你-咕咚同学 我把小龙虾搬到了微信-咕咚同学 安好 - 响石潭 Compound Engineering Plugin:让每个工程单元都比上一个更容易 MOSS-TTS Family:开源高质量语音与声音生成模型家族深度解析 Crawl4AI:专为 LLM 设计的开源 Web 爬虫与数据抓取工具 Build Your Own X:从零实现你最喜欢的技术——程序员进阶的终极资源清单 Anthropic Skills:用文件夹教 Claude 专业技能的开源框架 1年的去月球(下) - 梅之夏 欢迎回来。 简单讲讲 ASN.1 与 OID DTV - 直播聚合客户端 5.22-5.27 – 不兴江 还没去过鸭川 – 不兴江 张晶晶同学三刷林志颖 关于我 – 不兴江 爱与嫉妒 – 不兴江 港股被持续做空 备案码花了四百块-咕咚同学 一句话生成封面:我给公众号做了4种风格的AI封面生成技能 「官」方認證 再谈费曼学习法 2026-05-28T00:34:11+08:00 2026-05-28T00:28:45+08:00 离谱的英语学习指南:基于AI的英语进阶系统方法论 iii:零集成架构的后端统一运行时 Claude Code Harness:让 Claude Code 工作有迹可循的工程化框架 Heretic:全自动移除大语言模型审查机制的开源工具 MarkItDown:微软开源的万能文档转 Markdown 利器 Harness:让 Claude Code 秒变多智能体协作工厂 这段时间尽折腾AI Agent了,确实极大地提高了效率 近期动态:两个新站点正式上线啦 误判解除!zhouayuan.com 腾讯安全申诉成功 - 周阿源|玩具设计・插画日常・生活随笔 Ralph:让 AI 编码工具自主循环跑完所有 PRD 任务的量产神器 全都违法 – 个人工作记录 关于zhouayuan.com被误判 “含违规信息” 的说明与申诉记录 - 周阿源|玩具设计・插画日常・生活随笔 小米 MiMo v2.5 Pro 白嫖 最大的人间清醒,兜里有钱,但是不花。 夜晚靓歌(12):于文文现场solo - 王志勇的Blog 今日插画:风扬起的倔强 - 周阿源|玩具设计・插画日常・生活随笔 回门习俗 独立网卡 - 忘记了回忆 500亿入股人工智能企业 从命令行到桌面智能体-咕咚同学 第一性原理读书笔记 行者微评论223-加班の守株待兔-博客|政治与时事-风雨行者 ZOZO开源物理接触求解器:GPU加速的可扩展仿真引擎 OpenStock:开源股票市场交易平台技术深度解析 MoneyPrinterTurbo:基于AI的全自动短视频生成工具深度解析 Claude-Mem:为 Claude Code 构建的持久化记忆压缩系统 Twenty:可代码化定制的企业级开源 CRM 平台技术深度解析 2026-05-26T22:59:17+08:00 企业级开源大模型部署平台 GPUStack 实战教程 1年的去月球(上) - 梅之夏 Sevalla - 静态网站托管服务 不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code 装修灯具要注意⚠️ 黄梅天先锋 - 游子微博 公安备案顺利办结,站点备案全部完成 - 周阿源|玩具设计・插画日常・生活随笔 第三次兑换天猫超市卡了宗宗酱-三维狐少儿编程 Don't think, feel. - Rolen's Blog 人这一辈子,到底图个什么 博客迁移 - Edwin's Blog 情感赛道写作模板 再现本轮行情的典型特征 裁员与平常心-咕咚同学 别让“偷懒”,成为隐私泄露的破绽 片刻 - Jdeal | Life is like a Design.
golang学习之路:从入门到实践
santisify · 2026-06-20 · via BlogFinder

本人比较看重go的简洁性、跨平台不依赖运行时环境以及高并发(都是相对于Java),同时,我也比较侧重于后端开发,毕竟大部分理工男(懂的都懂)

我也算是开始自己的go语言学习了,但愿不要想java那样…

基础语法#

变量和常量数据类型#

//常量定义
const (
	StatusOK           = iota + 1    //iota是go语言的一个预定义标识符,表示常量生成器,在const关键字出现时被重置为0,并在每个const声明中自动递增。     
	StatusBadRequest                 //2
	StatusUnauthorized               //3
	MB                 = 1024 * 1024 //1048576
)

//变量定义
func main() {
	var str1 string = "Hello Go 1" //标准定义
	var str2 = "Hello Go 2"        //类型推断

	str3 := "Hello Go 3"          //短定义(通常用于函数中)
	fmt.Println(str1, str2, str3) //output:Hello Go 1 Hello Go 2 Hello Go 3
	str1, str2 = str2, str1       //交换str1与str2的值
	fmt.Println(str1, str2, str3) // output:Hello Go 2 Hello Go 1 Hello Go 3
}

//空值
func testNonInitValue() {
	var a int
	var b string
	var c float64
	fmt.Println(a, b, c) //output: 0 “” 0
	//上一行b输出的结果代表b的值是一个空字符串,而不是null或者undefined。
}


//至于类型转换,认真学过Java都知道
...

//类型自定义
type ll int64 // 定义一个新的类型ll,它的底层类型是int64
//为ll类型实现String方法,使其满足fmt.Stringer接口
func (l ll) String() string {
	return fmt.Sprintf("%d", l)
}
//结构体
type UserValue struct {
	name  string
	age   int
	email string
}
//同理,结构体也可以实现String方法
func (u UserValue) String() string {
	return fmt.Sprintf("name:%s, age:%d, email:%s)", u.name, u.age, u.email)
}
// slice
var arr [3]int       //只定义,为使用 output: 0,0,0
b := [3]int{1, 2, 3} //临时定义,并且附上初值 output:1,2,3
var c []int          //不定长
c1 = append(c, 1,2,3,4,5)
c2 := []int{1,2,3,4,5}
sc1 := make([]int, 0, len(c1)) // make函数创建一个长度为0,容量为len(c1)的切片
sc2 := new ([]int) // new函数创建一个指向长度为0的切片的指针

//map 键值对
m1 := map[string]int{"a": 1, "b": 2} //定义并初始化一个map output: map[a:1 b:2]
m2 := make(map[string]int)              //使用make函数创建一个空的map
m2["c"] = 3 //向map中添加一个键值对
for k, v := range m1 { // 使用range关键字遍历map,k代表键,v代表值
    fmt.Printf("key: %s, value: %d\n", k, v) //output: key: a, value: 1 \n key: b, value: 2
}

go

流程控制#

//if语句
if x > 0 {
    fmt.Println("x is positive")
} else if x < 0 {
    fmt.Println("x is negative")
} else {
    fmt.Println("x is zero")
}

//switch语句
switch day := time.Now().Weekday(); day {
case time.Monday:
    fmt.Println("It's Monday")
case time.Tuesday:
    fmt.Println("It's Tuesday")
default:
    fmt.Println("It's another day")
}

//for循环
for i := 0; i < 5; i++ {
    fmt.Println(i) //output: 0 1 2 3 4
}

//goto语句
func example() {
    fmt.Println("Start")
    goto Skip
    fmt.Println("This will be skipped")
Skip:
    fmt.Println("End")
}
//output: Start \n End

//select语句
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
    time.Sleep(1 * time.Second)
    ch1 <- "Hello from channel 1"
}()
go func() {
    time.Sleep(2 * time.Second)
    ch2 <- "Hello from channel 2"
}()
select {
case msg1 := <-ch1: 
    fmt.Println(msg1) //output: Hello from channel 1
case msg2 := <-ch2:
    fmt.Println(msg2) //output: Hello from channel 2
case <-time.After(3 * time.Second):
    fmt.Println("Timeout")
}

go

函数和方法#

//函数定义
func add(a int, b int) int {
	return a + b
}
//函数调用
result := add(3, 5) //output: 8
//方法定义
type Rectangle struct {
	width  float64
	height float64
}
func (r Rectangle) Area() float64 {
	return r.width * r.height
}
//方法调用
rect := Rectangle{width: 4, height: 5}
area := rect.Area() //output: 20

// 匿名函数
func() {
	fmt.Println("This is an anonymous function")
}() //output: This is an anonymous function

// 闭包
func makeAdder(x int) func(int) int {
	return func(y int) int {
		return x + y
	}
}
add5 := makeAdder(5)
result := add5(3) //output: 8

//可变参数
func sum(nums ...int) int {
	total := 0
	for _, num := range nums {
		total += num
	}
	return total
}
result := sum(1, 2, 3, 4) //output: 10

go

指针#

//指针定义
var p *int //定义一个指向int类型的指针
//指针赋值
x := 10
p = &x //将变量x的地址赋值给指针p
//指针解引用
value := *p //通过指针p获取x的值 output: 10
//指针修改值
*p = 20 //通过指针p修改x的值
fmt.Println(x) //output: 20

//指针与函数
func increment(n *int) {
	*n++ //通过指针n修改传入的值
}
num := 5
increment(&num) //传入num的地址
fmt.Println(num) //output: 6	

//指针与结构体
type Point struct {
	x int
	y int
}
p1 := Point{x: 1, y: 2}
p2 := &p1 //创建一个指向p1的指针
p2.x = 3 //通过指针p2修改p1的x值
fmt.Println(p1) //output: {3 2}

//指针与切片
func modifySlice(s []int) {
	s[0] = 100 //修改切片的第一个元素
}
slice := []int{1, 2, 3}
modifySlice(slice) //传入切片
fmt.Println(slice) //output: [100 2 3]

//二级指针
x := 10
p := &x
pp := &p
fmt.Println("x:", x, "p:", p, "pp:", pp, "**pp:", **pp) //output: x: 10 p:随机地址 pp: 随机地址 **pp: 10

go

错误处理#

//error类型
type error interface {
	Error() string
}

//defer语句
func example() {
	defer fmt.Println("This will be printed last")
	fmt.Println("This will be printed first")
}//output: This will be printed first \n This will be printed last

//panic和recover
func example() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered from panic:", r)
		}
	}()
	panic("Something went wrong") //触发panic
	fmt.Println("This will not be printed")
}//output: Recovered from panic: Something went wrong

go

Error样例:

package main

import (
	"fmt"
	"os"
	"time"
)

const (
	TimeFmt = "2006-01-02 15:04:05"
)

func main() {
	username, err := queryDatabase(100)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(username)
	}

	err = readFile("test.txt")
	if err != nil {
		fmt.Println(err)
	}

	a := []int{2, 4, 1, 24, 4, 32, 1, 243, 65, 43, 765, 23, 234}
	res, err := safeAccess(a, 100)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(res)
	}

	defres := deferReturn()
	fmt.Println("deferResult:", defres)
}

type BusinessError struct {
	Code    int
	Message string
	Time    time.Time
}

func (e *BusinessError) Error() string {
	return fmt.Sprintf("错误代码: %d \n 消息: %s \n 时间:%s \n",
		e.Code, e.Message, e.Time.Format(TimeFmt))
}

func queryDatabase(userID int) (string, error) {
	if userID <= 0 {
		return "", &BusinessError{
			Code:    400,
			Message: "用户不存在",
			Time:    time.Now(),
		}
	}
	if userID == 999 { //数据库连接超时
		return "", &BusinessError{
			Code:    401,
			Message: "数据库连接超时",
			Time:    time.Now(),
		}
	}
	return "李四", nil
}

func readFile(fileName string) error {
	file, err := os.Open(fileName)
	if err != nil {
		return fmt.Errorf("打开文件失败: %w", err)
	}
	defer file.Close()
	buf := make([]byte, 1024)
	_, err = file.Read(buf)
	if err != nil {
		return fmt.Errorf("读取文件失败: %w", err)
	}
	return nil
}

func safeAccess(arr []int, index int) (result int, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("panic: %v", r)
		}
	}()
	return arr[index], nil
}

func deferReturn() (result int) {  
	defer func() {  
		result++
	}()
	return 10
}

go