【Go语言】安装及使用基础教程
文章目录
- 1. 下载安装Go
- 官网安装
- 使用 Homebrew 安装 (Mac)
- 创建工作目录 (Workspace)
- 设置环境变量
- 通过 VSCode 扩展商店安装 Go 插件
- 处理权限问题
- 2. Hello, World 示例
- 3. 语法基础
- 变量声明
- 常量
- 数组
- 切片(Slice)
- Map(集合)
- 控制结构
- for 循环
- 基本形式:
- 类似 `while` 的形式:
- 无限循环:
- 条件判断
- 函数与指针
- 函数
- 指针
- 结构体与接口
- 结构体
- 接口
- 并发
- goroutine
- 通道(Channel)
- 错误处理
- 5. 常用数据结构和算法
- 1. 队列(Queue)
- 2. 栈(Stack)
- 3. 链表(Linked List)
- 4. 哈希表(Map)
- 5. 集合(Set)
- 6. 二叉树(Binary Tree)
- 7. 图(Graph)
- 8. 链表(Linked List)
1. 下载安装Go
官网安装
访问 Go官网,根据操作系统下载并安装对应版本。
使用 Homebrew 安装 (Mac)
brew update
brew install golang
创建工作目录 (Workspace)
在$HOME
目录下创建一个Go工作目录:
mkdir $HOME/go_workspace
设置环境变量
编辑终端配置文件(例如 ~/.zshrc
或 ~/.bashrc
),添加以下内容:
export GOROOT=/opt/homebrew/opt/go/libexec
export GOPATH=$HOME/go_workspace
export PATH=$PATH:$GOPATH/bin
export PATH=$PATH:$GOROOT/bin
通过 VSCode 扩展商店安装 Go 插件
-
打开 VSCode:
- 通过应用程序启动 VSCode 或者在终端中运行
code
命令(如果已安装 VSCode 命令行工具)。
- 通过应用程序启动 VSCode 或者在终端中运行
-
进入扩展商店:
- 在左侧工具栏中,点击“扩展”图标(看起来像一个四方的拼图块),或者使用快捷键
Command+Shift+X
打开扩展商店。
- 在左侧工具栏中,点击“扩展”图标(看起来像一个四方的拼图块),或者使用快捷键
-
搜索并安装 Go 插件:
- 在扩展商店的搜索框中,输入 “Go”,会看到由 Microsoft 提供的官方 Go 扩展。
- 点击 “Install” 按钮进行安装。
-
自动安装工具:
- 安装插件后,当你首次打开一个 Go 项目或 Go 文件时,VSCode 通常会自动提示你安装所需的工具。如果有此提示,选择“安装所有工具”即可。
- 如果没有提示,仍然可以使用
Command+Shift+P
打开命令面板,输入Go: Install/Update Tools
,然后选择并安装所有相关工具。
处理权限问题
如果在安装工具时遇到权限问题,如权限被拒绝(Permission Denied)或 /usr/local/pkg
目录不存在,可以使用以下命令修复权限问题:
sudo mkdir /usr/local/pkg
sudo chown -R $(whoami) /usr/local/pkg
这会创建所需的目录并将其权限设置为当前用户,从而避免权限问题。
2. Hello, World 示例
新建一个 hello.go
文件,内容如下:
package mainimport "fmt"func main() {fmt.Println("Hello, Go!")
}
运行程序:
go run hello.go
输出结果:
Hello, Go!
生成可执行文件:
go build hello.go
./hello
3. 语法基础
变量声明
Go 语言使用 var
关键字声明变量,语法为:
var identifier type
示例:
package mainimport "fmt"var a string = "Geek Go" // 变量声明在函数外部func main() {fmt.Println(a) // 输出:Geek Go,函数体内可以放执行代码
}
简化版:
package mainimport "fmt"var a string = "Geek Go" // 变量声明在函数外部func main() {fmt.Println(a) // 输出:Geek Go,函数体内可以放执行代码b, c := 1, 2 // 自动推断类型为 intfmt.Println(b, c) // 输出:1 2
}
常量
常量使用 const
关键字来声明:
package mainimport "fmt"func main() {const pi = 3.14 // 声明常量fmt.Println("Pi的值是:", pi)
}
数组
数组声明并使用 for
循环遍历:
package mainimport "fmt"func main() {var arr [5]int = [5]int{1, 2, 3, 4, 5}// 使用 for 循环遍历数组for i := 0; i < len(arr); i++ {fmt.Println(arr[i])}
}
切片(Slice)
切片是长度可变的动态数组:
package mainimport "fmt"func main() {slice := []int{1, 2, 3, 4, 5}// 打印切片的一部分fmt.Println(slice[1:4]) // 输出:[2 3 4]// 向切片添加元素slice = append(slice, 6, 7)fmt.Println("追加后的切片:", slice)
}
Map(集合)
Map 是键值对的集合:
package mainimport "fmt"func main() {// 创建一个 Mapcars := make(map[string]string)cars["A"] = "Audi"cars["B"] = "BMW"cars["T"] = "Tesla"// 遍历 Mapfor k, v := range cars {fmt.Printf("%s -> %s\n", k, v)}
}
控制结构
for 循环
Go 语言的 for
循环有三种常见形式:
基本形式:
package mainimport "fmt"func main() {for i := 0; i < 5; i++ {fmt.Println(i)}
}
类似 while
的形式:
package mainimport "fmt"func main() {i := 0for i < 5 {fmt.Println(i)i++}
}
无限循环:
package mainimport "fmt"func main() {for {fmt.Println("This will run forever")break // 使用 break 来防止无限循环}
}
条件判断
使用 if
语句进行条件判断:
package mainimport "fmt"func main() {x := 10if x > 10 {fmt.Println("x is greater than 10")} else {fmt.Println("x is 10 or less")}
}
函数与指针
函数
Go 中函数的定义和调用:
package mainimport "fmt"// 定义一个函数来求两个数的和
func add(x int, y int) int {return x + y
}func main() {result := add(3, 4)fmt.Println("3 + 4 =", result)
}
指针
Go 中指针的使用:
package mainimport "fmt"func main() {x := 10var p *intp = &x // 获取变量x的地址fmt.Println("x的值是:", x)fmt.Println("p指向的地址是:", p)fmt.Println("p指向的值是:", *p) // 通过指针访问值
}
结构体与接口
结构体
结构体用于定义复杂数据类型:
package mainimport "fmt"// 定义一个结构体
type Book struct {title stringauthor stringprice float32
}func main() {// 创建结构体实例book := Book{title: "Go语言教程", author: "GeekHall", price: 9.9}// 输出结构体内容fmt.Println(book)
}
结构体作为函数参数:
package mainimport "fmt"// 定义一个结构体
type Book struct {title stringauthor stringprice float32
}// 定义一个打印书籍信息的函数
func printBook(book *Book) {fmt.Println("书名:", book.title)fmt.Println("作者:", book.author)fmt.Println("价格:", book.price)
}func main() {book := Book{title: "Go语言教程", author: "GeekHall", price: 9.9}printBook(&book) // 传递指针
}
接口
接口定义一组方法,任何实现了这些方法的类型都实现了该接口:
package mainimport "fmt"// 定义一个接口
type ICar interface {drive()
}// 定义实现接口的结构体
type Tesla struct{}func (t Tesla) drive() {fmt.Println("I am a Tesla")
}func main() {var car ICar = Tesla{}car.drive()
}
并发
goroutine
使用 go
关键字启动一个新的并发任务:
package mainimport "fmt"func concurrentTest(s string) {for i := 0; i < 5; i++ {fmt.Println(s)}
}func main() {go concurrentTest("Tesla")concurrentTest("Toyota")
}
通道(Channel)
通道用于在 goroutine 之间传递数据:
package mainimport "fmt"// 定义一个求和函数,结果通过通道传递
func sum(s []int, c chan int) {sum := 0for _, v := range s {sum += v}c <- sum // 发送结果到通道
}func main() {s := []int{7, 2, 8, -9, 4, 0}c := make(chan int)go sum(s[:len(s)/2], c)go sum(s[len(s)/2:], c)x, y := <-c, <-c // 从通道接收结果fmt.Println(x, y, x+y)
}
错误处理
Go 提供了内置的 error
接口用于错误处理:
package mainimport ("errors""fmt"
)func divide(a, b int) (int, error) {if b == 0 {return 0, errors.New("division by zero")}return a / b, nil
}func main() {result, err := divide(10, 0)if err != nil {fmt.Println("Error:", err)} else {fmt.Println("Result:", result)}
}
5. 常用数据结构和算法
1. 队列(Queue)
队列是一种先进先出(FIFO)的数据结构,可以使用切片(Slice)来模拟队列的操作:
package mainimport "fmt"func main() {queue := []int{1, 2, 3}// 入队queue = append(queue, 4)fmt.Println("队列状态:", queue)// 出队head := queue[0]queue = queue[1:]fmt.Println("队头元素:", head)fmt.Println("出队后的队列:", queue)
}
2. 栈(Stack)
栈是一种后进先出(LIFO)的数据结构,也可以使用切片来模拟栈的操作:
package mainimport "fmt"func main() {stack := []int{}// 入栈stack = append(stack, 1)stack = append(stack, 2)stack = append(stack, 3)fmt.Println("栈状态:", stack)// 出栈top := stack[len(stack)-1]stack = stack[:len(stack)-1]fmt.Println("栈顶元素:", top)fmt.Println("出栈后的栈:", stack)
}
3. 链表(Linked List)
Go 标准库没有直接提供链表的实现,但可以使用 container/list
包来创建双向链表:
package mainimport ("container/list""fmt"
)func main() {// 创建一个双向链表l := list.New()// 插入元素l.PushBack(1)l.PushBack(2)l.PushBack(3)// 遍历链表for e := l.Front(); e != nil; e = e.Next() {fmt.Println(e.Value)}// 删除第一个元素l.Remove(l.Front())fmt.Println("删除第一个元素后:")for e := l.Front(); e != nil; e = e.Next() {fmt.Println(e.Value)}
}
4. 哈希表(Map)
Go 内置 map
类型来实现哈希表(键值对映射):
package mainimport "fmt"func main() {// 创建一个 mapfruits := map[string]string{"apple": "red","banana": "yellow","grape": "purple",}// 打印 mapfor fruit, color := range fruits {fmt.Printf("%s is %s\n", fruit, color)}// 查找元素color, found := fruits["apple"]if found {fmt.Println("The color of apple is", color)} else {fmt.Println("Apple not found!")}// 删除元素delete(fruits, "banana")fmt.Println("删除后:", fruits)
}
5. 集合(Set)
Go 没有直接提供 Set
类型,但可以使用 map
来模拟集合。map
的键代表集合的元素,值可以忽略或设置为 true
。
package mainimport "fmt"func main() {// 使用 map 模拟集合set := make(map[string]bool)// 添加元素set["apple"] = trueset["banana"] = trueset["orange"] = true// 检查元素是否存在if set["apple"] {fmt.Println("集合中有 apple")}// 删除元素delete(set, "banana")fmt.Println("删除 banana 后的集合:", set)// 遍历集合fmt.Println("集合中的元素:")for fruit := range set {fmt.Println(fruit)}
}
6. 二叉树(Binary Tree)
Go 标准库没有提供树结构,但可以手动实现二叉树。以下是一个简单的二叉搜索树的实现:
package mainimport "fmt"// 定义二叉树节点
type TreeNode struct {value intleft *TreeNoderight *TreeNode
}// 插入元素到二叉搜索树
func insert(node *TreeNode, value int) *TreeNode {if node == nil {return &TreeNode{value: value}}if value < node.value {node.left = insert(node.left, value)} else {node.right = insert(node.right, value)}return node
}// 中序遍历二叉树
func inorderTraversal(node *TreeNode) {if node != nil {inorderTraversal(node.left)fmt.Println(node.value)inorderTraversal(node.right)}
}func main() {var root *TreeNodevalues := []int{8, 3, 10, 1, 6, 14, 4, 7, 13}for _, value := range values {root = insert(root, value)}fmt.Println("二叉树的中序遍历:")inorderTraversal(root)
}
7. 图(Graph)
图可以使用邻接表来表示,Go 中可以用 map[string][]string
实现邻接表:
package mainimport "fmt"// 图的邻接表表示
type Graph struct {edges map[string][]string
}// 添加边
func (g *Graph) addEdge(node, neighbor string) {g.edges[node] = append(g.edges[node], neighbor)
}// 打印图
func (g *Graph) printGraph() {for node, neighbors := range g.edges {fmt.Printf("%s -> %v\n", node, neighbors)}
}func main() {g := Graph{edges: make(map[string][]string)}g.addEdge("A", "B")g.addEdge("A", "C")g.addEdge("B", "D")g.addEdge("C", "E")g.printGraph()
}
8. 链表(Linked List)
Go 的 container/list
标准库支持双向链表。以下代码展示如何插入和遍历链表:
package mainimport ("container/list""fmt"
)func main() {// 创建链表myList := list.New()// 在链表末尾添加元素myList.PushBack(1)myList.PushBack(2)myList.PushBack(3)// 遍历链表for element := myList.Front(); element != nil; element = element.Next() {fmt.Println(element.Value)}
}
相关文章:

【Go语言】安装及使用基础教程
文章目录 1. 下载安装Go官网安装使用 Homebrew 安装 (Mac)创建工作目录 (Workspace)设置环境变量通过 VSCode 扩展商店安装 Go 插件处理权限问题 2. Hello, World 示例3. 语法基础变量声明常量数组切片(Slice)Map(集合)控制结构fo…...

【大模型】3分钟了解提示(Prompt)工程、检索增强(RAG)和微调
我们先看下面这个图: 简单理解大模型是通过海量训练数据训练出来的,它的能力非常强,但是有时候会给出错误的回答。那产生错误的原因可能是什么呢? 1.提问错误(提示工程) 在我们提问的方式不对的情况下&a…...

太速科技-509-基于XCVU13P的4路QSFP28光纤PCIeX16收发卡
基于XCVU13P的4路QSFP28光纤PCIeX16收发卡 一、板卡概述 基于XCVU13P的4路QSFP28光纤PCIeX16收发卡。该板卡要求符合PCIe 3.0标准,包含一片XCVU13P-2FLGA2014I、4组64-bit/8GB DDR4;4路QSFP28 4X光纤,每路光纤支持4X25Gbps&#…...

C#从零开始学习(基本语法概念)(2)
深入C# 本章所有的代码都放在 https://github.com/hikinazimi/head-first-Csharp 控制台项目结构 每个C#程序采用同样的方式组织,命名空间,类和方法 using System;namespace helloworld//命名空间 {class Program//类{static void Main(string[] args)//程序入口{Console.Writ…...

基于SSM+微信小程序的家庭记账本管理系统(家庭1)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 1、管理员端功能有首页、个人中心、用户管理,消费详情管理、收入详情管理、系统管理等。 2、用户端功能有首页、消费详情、收入详情、论坛信息、我的等功能。 2、项目技术 …...

MEMC功能详解
文章目录 MEMC的工作原理:优点:缺点:适用场景:1. Deblur(去模糊)2. Dejudder(去抖动)总结两者区别: MEMC(Motion Estimation and Motion Compensation&#x…...

C++ | Leetcode C++题解之第493题翻转对
题目: 题解: class BIT { private:vector<int> tree;int n;public:BIT(int _n) : n(_n), tree(_n 1) {}static constexpr int lowbit(int x) {return x & (-x);}void update(int x, int d) {while (x < n) {tree[x] d;x lowbit(x);}}in…...

Git 修改分支名
在Git中修改分支名称,可以使用以下步骤: 切换到要重命名分支之外的其他分支: git checkout <其他分支名>重命名本地分支: git branch -m <旧分支名> <新分支名>如果需要删除远程的旧分支并创建新分支࿱…...

[自动化测试:Selenium]:环境部署和Webdriver的使用
文章目录 修改安装源打开Python Packages。点击梅花按钮。在弹出的对话框中,填入Name(随便填),Repository URL,选择下列的源,一般先选择清华源按OK确认。配置完成 安装seleniumFile→Settings→Project&…...

51单片机——OLED显示图片
取模软件:链接:https://pan.baidu.com/s/1UcrbS7nU4bsawNxsaaULfQ 提取码:gclc 1、如果图片大小和格式不合适,可以先用Img2Lcd软件进行调整图片大小,一般取模软件使用的是.bmp图片,可以进行输出.bmp格式。软件界面如下࿱…...

Gin 协程mysql客户端
一、Gin框架 mysql配置 这里选择yaml文件配置 二、配置读取 viper 读取yaml文件中对应配置 三、mysql 的协程客户端 文件位置 package databaseimport ("database/sql""fmt""github.com/spf13/viper""log""net/http"&quo…...

量子门电路开销——T门、clifford门、toffoli门、fredkin门
在量子计算中,T门的成本比Clifford门高出很多倍的原因与量子计算中纠错的实现、物理门操作的复杂性以及容错量子计算架构中的成本评估有关。以下是几个关键原因,解释了为什么 T 门的成本在量子计算中远远高于 Clifford 门: 1. T 门和 Cliffo…...

C++之《剑指offer》学习记录(1):类型转换关键字
笔者最近在找工作时,无意间读到了一本名为《剑指offer》的书,粗略翻阅了一下,感觉这将会是一本能让我不再苦恼于笔试和面试“手搓代码”的书。故笔者写下该系列博客记录自己的学习历程,希望能和这本书的读者朋友们一起交流学习心得…...

【Linux】平台设备驱动
在设备驱动模型中,引入总线的概念可以对驱动代码和设备信息进行分离。但是驱动中总线的概念是软件层面的一种抽象,与我们SOC中物理总线的概念并不严格相等。 物理总线:芯片与各个功能外设之间传送信息的公共通信干线,其中又包括数…...

【Linux】命令行参数环境变量
文章目录 命令行参数环境变量环境变量的概念常见环境变量查看环境变量测试PATH修改PATH HOME和环境变量相关的命令环境变量是如何被组织的通过系统调用putenv和getenv获取或设置环境变量环境变量通常是具有全局属性的普通变量与环境变量的区别 命令行参数 main函数有三种形式&…...

libaom 源码分析:twopass_encoder.c 文件
libaom libaom 是 AOMedia(开放媒体联盟)开发的一个开源视频编解码器库,它是 AV1 视频压缩格式的参考实现,并被广泛用于多种生产系统中。libaom 支持多种功能,包括可扩展视频编码(SVC)、实时通信…...

ruoyi同时支持mysql+sqlserver+oracle+postgresql
需求背景 最近需要一个小demo,项目中需要同时连接sqlserver和mysql数据库。 操作教程 1、pom.xml -- 修改common/pom.xml<!-- 动态数据源 --> <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-star…...

微信小程序绘制轨迹
1、map | uni-app官网 根据官网描述:通过从数据库获取POI数据,并通过 uni-id-common 内的路线规划API,计算路线、距离、时间。 2、 <map style"width:100%;height:96%;" id"myMap" :scale"scale" :longi…...

UNION 联合查询
1.UNION ALL联合查询 同样为了演示方便,先向 teacher 表插入多条测试数据: INSERT INTO teacher (name,age,id_number,email) VALUES (姓名一,17,42011720200604077X,NULL), (姓名二,18,42011720200604099X,123qq.com), (姓名三,19,42011720200604020X…...

blender 理解 积木组合 动画制作 学习笔记
一、学习blender视频教程链接 案例2:积木组合_动画制作_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Bt4y1E7qn?vd_sourced0ea58f1127eed138a4ba5421c577eb1&p10&spm_id_from333.788.videopod.episodes 二、说明 之前已经学习了如何制作积木组…...

关于 FreeSWITCH mod_sofia 注册过期时间的测试
FreeSWITCH 版本:1.10.12,以下简称 Fs SIP 终端:Eyebeam 1.5.14.4 Eyebeam 设置注册的过期时间为 30 Fs 设置为 120,下面是详细配置: <param name"sip-force-expires-max" value"120"/>…...

【LeetCode:349. 两个数组的交集 + 哈希表】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...

根据语音生成视频33搜帧
33搜帧,是一个能根据语音生成视频的网站,33搜帧 - 视频帧画面搜索引擎 33搜帧是一个使用AI技术构建的视频帧画面搜索引擎,和一般素材平台通过视频标签来搜索视频不同,33搜帧能搜索到视频素材中的每一帧画面,这个功能可…...

目标检测数据集图片及标签同步锐化
在目标检测任务中,数据集的质量直接影响到模型的性能。数据增强作为提升数据集多样性和模型泛化能力的常用手段,在图像处理过程中扮演着重要角色。锐化(Sharpening)技术是常见的图像增强方法之一,能够突出图像中的细节…...

滚雪球学Redis[6.4讲]:Redis消息队列:构建高效的消息通信与任务调度系统
全文目录: 🎉前言🚦Redis消息队列的使用场景🐳1. 异步任务处理🐋2. 任务调度🐬3. 模块解耦 ⚙️实现发布/订阅模型🐟️1. 发布者发布消息🐠2. 订阅者订阅频道🐡3. 实际应…...

《计算机视觉》—— 换脸
效果如下: 完整代码: import cv2 import dlib import numpy as npJAW_POINTS list(range(0, 17)) RIGHT_BROW_POINTS list(range(17, 22)) LEFT_BROW_POINTS list(range(22, 27)) NOSE_POINTS list(range(27, 35)) RIGHT_EYE_POINTS list(range(36…...

【JavaEE初阶】深入透析文件-IO关于文件内容的操作(四种文件流)
前言 🌟🌟本期讲解关于CAS的补充和JUC中有用的类,这里涉及到高频面试题哦~~~ 🌈上期博客在这里:【JavaEE初阶】文件-IO之实现文件系统的操作如何进行实现-CSDN博客 🌈感兴趣的小伙伴看一看小编主页&…...

复习:react 中的 refs,怎么使用,有哪些使用场景
在 React 中,refs(引用)是一个重要的特性,它允许开发者直接访问 DOM 元素或者 React 组件的实例。以下是对 React 中 refs 的使用及其使用场景的详细解释: 一、refs 的使用方法 字符串引用 在早期的 React 版本中,可以通过字符串来设置 ref。然而,这种方法已经被废弃,…...

Python OpenCV精讲系列 - 目标检测与识别深入理解(二十)
💖💖⚡️⚡️专栏:Python OpenCV精讲⚡️⚡️💖💖 本专栏聚焦于Python结合OpenCV库进行计算机视觉开发的专业教程。通过系统化的课程设计,从基础概念入手,逐步深入到图像处理、特征检测、物体识…...

golang中的上下文
背景 在Go语言中,使用context包来管理跨API和进程间的请求生命周期是常见的做法。特别是在涉及到并发编程时,如启动协程(goroutine)来处理异步任务,正确地传递和监听context变得尤为重要。比如,在gin框架中…...