当前位置: 首页 > news >正文

读《Go语言圣经》记录(一)

读《Go语言圣经》记录(一)

在编程语言的海洋中,Go语言以其简洁的语法、高效的并发处理能力和强大的标准库迅速崭露头角,成为开发者的宠儿。本文将带大家深入探索《Go语言圣经》的入门章节,并结合实际示例和扩展知识,开启一段精彩的Go语言学习之旅。

第一章:入门

1.1 Hello, World

每个编程之旅都从“Hello, World”开始。在Go语言中,编写一个简单的“Hello, World”程序易如反掌。以下是代码示例:

package mainimport "fmt"func main() {fmt.Println("Hello, 世界")
}

这段代码展示了Go语言的基本结构:package main声明了程序的入口包,import "fmt"引入了格式化I/O包,func main()是程序的入口函数,而fmt.Println则用于输出文本。运行这段代码,你将在控制台看到“Hello, 世界”的友好问候。

1.2 命令行参数

Go语言通过os包提供对命令行参数的访问。以下是一个示例,展示如何读取并处理命令行参数:

package mainimport ("fmt""os"
)func main() {args := os.Argsfor i, arg := range args {fmt.Printf("Argument %d: %s\n", i, arg)}
}

将此代码保存为args.go,然后通过命令行运行go run args.go arg1 arg2,你将看到程序输出传递给它的参数。

1.3 查找重复的行

处理文本数据是编程中的常见任务。下面是一个程序,用于查找输入中的重复行:

package mainimport ("bufio""fmt""os"
)func main() {counts := make(map[string]int)input := bufio.NewScanner(os.Stdin)for input.Scan() {line := input.Text()counts[line]++}for line, count := range counts {if count > 1 {fmt.Printf("%d\t%s\n", count, line)}}
}

将此代码保存为dups.go,然后通过管道传递文本文件内容,如cat file.txt | go run dups.go,程序将输出文件中重复的行及其出现次数。

1.4 GIF动画

Go的imagegif包使得创建图像和动画变得简单。以下是一个生成GIF动画的示例:

package mainimport ("image""image/color""image/gif""math""os"
)func main() {const (cycles  = 5res     = 0.001size    = 100nframes = 64delay   = 8)anim := gif.GIF{LoopCount: nframes}palette := []color.Color{color.White, color.Black}for i := 0; i < nframes; i++ {rect := image.Rect(0, 0, 2*size+1, 2*size+1)img := image.NewPaletted(rect, palette)for t := 0.0; t < cycles*2*math.Pi; t += res {x := math.Sin(t)y := math.Sin(t*1.5)img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), 1)}anim.Delay = append(anim.Delay, delay)anim.Image = append(anim.Image, img)}gif.EncodeAll(os.Stdout, &anim)
}

运行此程序并将输出重定向到GIF文件,如go run lissajous.go > out.gif,你将得到一个美丽的GIF动画。

1.5 获取URL

Go的net/http包提供了强大的HTTP客户端功能。以下是如何获取网页内容的示例:

package mainimport ("fmt""io/ioutil""net/http""os"
)func main() {resp, err := http.Get("https://example.com")if err != nil {fmt.Fprintf(os.Stderr, "fetch: %v\n", err)os.Exit(1)}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", resp.Request.URL, err)os.Exit(1)}fmt.Printf("%s", body)
}

将此代码保存为fetch.go并运行go run fetch.go https://example.com,你将在控制台看到网页的HTML内容。

1.6 并发获取多个URL

Go的并发模型是其最大的亮点之一。通过goroutines和channels,可以轻松地并发获取多个URL:

package mainimport ("fmt""io""net/http""os""time"
)func main() {start := time.Now()ch := make(chan string)for _, url := range os.Args[1:] {go fetch(url, ch)}for range os.Args[1:] {fmt.Println(<-ch)}fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
}func fetch(url string, ch chan<- string) {start := time.Now()resp, err := http.Get(url)if err != nil {ch <- fmt.Sprintf("error: fetching %s: %v", url, err)return}defer resp.Body.Close()nbytes, err := io.Copy(io.Discard, resp.Body)if err != nil {ch <- fmt.Sprintf("error: reading %s: %v", url, err)return}secs := time.Since(start).Seconds()ch <- fmt.Sprintf("%.2fs  %7d  %s", secs, nbytes, url)
}

运行此程序并传递多个URL作为参数,你将看到每个URL的获取时间和数据大小。

1.7 Web服务

创建一个简单的Web服务器来响应HTTP请求:

package mainimport ("fmt""net/http"
)func handler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
}func main() {http.HandleFunc("/", handler)http.ListenAndServe("localhost:8000", nil)
}

运行此程序并在浏览器中访问http://localhost:8000,你将看到请求的URL路径。

1.8 本章要点

本章涵盖了Go语言的基础知识,包括如何编写和运行程序、处理命令行参数、文本处理、图像生成、网络编程和并发编程。通过这些示例,我们不仅学习了Go语言的语法,还了解了其强大的标准库和并发模型。

扩展知识与最佳实践

错误处理

在处理外部操作(如文件I/O或网络请求)时,总是检查错误并进行适当的处理:

resp, err := http.Get(url)
if err != nil {log.Fatal(err)
}
defer resp.Body.Close()

使用defer确保资源被正确释放。

并发模式

Go的并发模型基于CSP(Communicating Sequential Processes)。使用goroutineschannels来协调并发任务:

ch := make(chan int)
go func() {for i := 0; i < 3; i++ {ch <- i}close(ch)
}()
for num := range ch {fmt.Println(num)
}

性能优化

使用sync.Pool来重用对象,减少内存分配和垃圾回收的开销:

var pool = sync.Pool{New: func() interface{} {return make([]byte, 1024)},
}func getBuffer() []byte {return pool.Get().([]byte)
}func putBuffer(b []byte) {pool.Put(b)
}

相关文章:

  • uni-app学习笔记十三-vue3中slot插槽的使用
  • QML与C++交互2
  • 【电子通识】连接器的绝缘胶座和接触端子基础知识
  • 数据结构 栈的详细解析
  • Java——优先级队列(堆)
  • 明阳智慧能源社招校招入职测评 |iLogic言语逻辑数字、Talent5大五职业性格测评、TAS倍智人才测评考什么
  • JVM规范之栈帧
  • 我的第1个爬虫程序——豆瓣Top250爬虫的详细步骤指南
  • uni-app学习笔记十二-vue3中组件传值(对象传值)
  • 字节跳动GPU Scale-up互联技术白皮书
  • 【数据结构】实现方式、应用场景与优缺点的系统总结
  • 基于Android的军训app的设计与实现
  • Leetcode 刷题记录 10 —— 二叉树
  • OpenGL环境配置
  • c++ overwrite
  • OpenCV 第7课 图像处理之平滑(二)
  • springboot中拦截器配置使用
  • windows和mac安装虚拟机-详细教程
  • 新闻推荐预测系统实战指南
  • html学习
  • 毕业设计做网站/企业关键词排名优化网址
  • 江津网站建设方案/青岛网站优化公司
  • 常州模板网站建设企业/免费个人网站建站
  • 中国建设购物网站/刚刚突发1惊天大事
  • 无锡网站建设多少钱/种子搜索引擎
  • 定制礼品公司/湖南seo快速排名