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

推荐订阅源

Y
Y Combinator Blog
有赞技术团队
有赞技术团队
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
人人都是产品经理
人人都是产品经理
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
The Cloudflare Blog
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
Vercel News
Vercel News
IT之家
IT之家
MyScale Blog
MyScale Blog
博客园_首页
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
罗磊的独立博客

博客 on 打工人日志

k8s RKE2 cilium L2 + envoy gateway 安装配置 k8s RKE2 vSphere 存储配置 OpenClaw 全能指南:从安装到进阶自动化实战 (2026 最终版) Kubernetes — skywalking + banyanDB APM监控部署 Kubernetes — promtail + loki + grafana 日志系统部署 k8s master 节点 Unauthorized Kubernetes — metalLB + Traefik 部署 Kubernetes — SSL 证书自动更新 Kubernetes — RKE2 + kube-vip + cilium 部署 使用TLSv1.3 升级nginx和openssl Proxmox VE(PVE) 更新到最新版本 kindle 邮件发送失败,错误代码E999 metallb + ingress-nginx + argocd 本地部署 iStoreOS(旁路由)使用openclash实现dns劫持 异常流量分析:图片库服务黑客入侵 openwrt 硬盘扩容 搭建ip地址检索服务 Kubernetes — k8s 手动安装 1.17.9 SELinux 问题:导致端口无法创建,无法访问 【福利】免费!本地部署!去除视频中移动的物体 通知:《打工人日报》迁移到独立板块 KyBook 3 | calibre-web - IOS系统最佳图书伴侣 Tmux 安装和使用教程 DockerHub 加速镜像部署 - 使用cloudflare 代理 docker的零停机部署 SD-webui 批量处理图片 ubuntu 安装 ComfyUI ubuntu 安装 stable-diffusion-webui 测试策略:微服务架构 单元测试:测试单元质量提升
go 基础知识
2022-04-25 · via 博客 on 打工人日志

go 基础知识

目录结构

1├─ code  -- 代码根目录
2│  ├─ bin
3│  ├─ pkg
4│  ├─ src
5│     ├── hello
6│         ├── hello.go
  • bin 存放编译后可执行的文件。
  • pkg 存放编译后的应用包。
  • src 存放应用源代码。

Hello World 代码

 1//在 hello 目录下创建 hello.go
 2package main
 3
 4import (
 5	"fmt"
 6)
 7
 8func main() {
 9	fmt.Println("Hello World!")
10}

基础命令

1go build hello
2#在src目录或hello目录下执行 go build hello,只在对应当前目录下生成文件。
3go install hello
4#在src目录或hello目录下执行 go install hello,会把编译好的结果移动到 $GOPATH/bin。
5go run hello
6#在src目录或hello目录下执行 go run hello,不生成任何文件只运行程序。
7go fmt hello
8#在src目录或hello目录下执行 go run hello,格式化代码,将代码修改成标准格式。

数据类型

类型表示备注
字符串string只能用一对双引号("")或反引号(``)括起来定义,不能用单引号(’’)定义!
布尔bool只有 true 和 false,默认为 false。
整型int8 uint8 int16 uint16 int32 uint32 int64 uint64 int uint具体长度取决于 CPU 位数。
浮点型float32 float64

常量声明

常量,在程序编译阶段就确定下来的值,而程序在运行时无法改变该值。

1. 单个常量声明

第一种:const 变量名称 数据类型 = 变量值
如果不赋值,使用的是该数据类型的默认值。
第二种:const 变量名称 = 变量值
根据变量值,自行判断数据类型。

2. 多个常量声明

第一种:const 变量名称,变量名称 … ,数据类型 = 变量值,变量值 …
第二种:const 变量名称,变量名称 … = 变量值,变量值 …

3. 代码

 1//demo_1.go
 2package main
 3
 4import (
 5	"fmt"
 6)
 7
 8func main() {
 9	const name string = "Tom"
10	fmt.Println(name)
11
12	const age = 30
13	fmt.Println(age)
14
15	const name_1, name_2 string = "Tom", "Jay"
16	fmt.Println(name_1, name_2)
17
18	const name_3, age_1 = "Tom", 30
19	fmt.Println(name_3, age_1)
20}

变量声明

单个变量声明

第一种:var 变量名称 数据类型 = 变量值
如果不赋值,使用的是该数据类型的默认值。
第二种:var 变量名称 = 变量值
根据变量值,自行判断数据类型。
第三种:变量名称 := 变量值
省略了 var 和数据类型,变量名称一定要是未声明过的。

多个变量声明

第一种:var 变量名称,变量名称 … ,数据类型 = 变量值,变量值 …
第二种:var 变量名称,变量名称 … = 变量值,变量值 …
第三种:变量名称,变量名称 … := 变量值,变量值 …

代码

 1//demo_2.go
 2package main
 3
 4import (
 5	"fmt"
 6)
 7
 8func main() {
 9	var age_1 uint8 = 31
10	var age_2 = 32
11	age_3 := 33
12	fmt.Println(age_1, age_2, age_3)
13
14	var age_4, age_5, age_6 int = 31, 32, 33
15	fmt.Println(age_4, age_5, age_6)
16
17	var name_1, age_7 = "Tom", 30
18	fmt.Println(name_1, age_7)
19
20	name_2, is_boy, height := "Jay", true, 180.66
21	fmt.Println(name_2, is_boy, height)
22}

输出方法

fmt.Print:输出到控制台(仅只是输出)

fmt.Println:输出到控制台并换行

fmt.Printf:仅输出格式化的字符串和字符串变量(整型和整型变量不可以)

fmt.Sprintf:格式化并返回一个字符串,不输出。

代码

 1//demo_3.go
 2package main
 3
 4import (
 5	"fmt"
 6)
 7
 8func main() {
 9	fmt.Print("输出到控制台不换行")
10	fmt.Println("---")
11	fmt.Println("输出到控制台并换行")
12	fmt.Printf("name=%s,age=%d\n", "Tom", 30)
13	fmt.Printf("name=%s,age=%d,height=%v\n", "Tom", 30, fmt.Sprintf("%.2f", 180.567))
14}

数组

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成,一旦声明了,数组的长度就固定了,不能动态变化。

len()cap() 返回结果始终一样。

声明数组

 1package main
 2
 3import (
 4	"fmt"
 5)
 6
 7func main() {
 8	//一维数组
 9	var arr_1 [5] int
10	fmt.Println(arr_1)
11
12	var arr_2 =  [5] int {1, 2, 3, 4, 5}
13	fmt.Println(arr_2)
14
15	arr_3 := [5] int {1, 2, 3, 4, 5}
16	fmt.Println(arr_3)
17
18	arr_4 := [...] int {1, 2, 3, 4, 5, 6}
19	fmt.Println(arr_4)
20
21	arr_5 := [5] int {0:3, 1:5, 4:6}
22	fmt.Println(arr_5)
23
24	//二维数组
25	var arr_6 = [3][5] int {{1, 2, 3, 4, 5}, {9, 8, 7, 6, 5}, {3, 4, 5, 6, 7}}
26	fmt.Println(arr_6)
27
28	arr_7 :=  [3][5] int {{1, 2, 3, 4, 5}, {9, 8, 7, 6, 5}, {3, 4, 5, 6, 7}}
29	fmt.Println(arr_7)
30
31	arr_8 :=  [...][5] int {{1, 2, 3, 4, 5}, {9, 8, 7, 6, 5}, {0:3, 1:5, 4:6}}
32	fmt.Println(arr_8)
33}

注意事项

一、数组不可动态变化问题,一旦声明了,其长度就是固定的。

1var arr_1 = [5] int {1, 2, 3, 4, 5}
2arr_1[5] = 6
3fmt.Println(arr_1)

运行会报错:invalid array index 5 (out of bounds for 5-element array)

二、数组是值类型问题,在函数中传递的时候是传递的值,如果传递数组很大,这对内存是很大开销。

 1//demo_5.go
 2package main
 3
 4import (
 5	"fmt"
 6)
 7
 8func main() {
 9	var arr =  [5] int {1, 2, 3, 4, 5}
10	modifyArr(arr)
11	fmt.Println(arr)
12}
13
14func modifyArr(a [5] int) {
15	a[1] = 20
16}
 1//demo_6.go
 2package main
 3
 4import (
 5	"fmt"
 6)
 7
 8func main() {
 9	var arr =  [5] int {1, 2, 3, 4, 5}
10	modifyArr(&arr)
11	fmt.Println(arr)
12}
13
14func modifyArr(a *[5] int) {
15	a[1] = 20
16}

三、数组赋值问题,同样类型的数组(长度一样且每个元素类型也一样)才可以相互赋值,反之不可以。

1var arr =  [5] int {1, 2, 3, 4, 5}
2var arr_1 [5] int = arr
3var arr_2 [6] int = arr

运行会报错:cannot use arr (type [5]int) as type [6]int in assignment