【Go语言圣经1.5】

目标

概念

要点(案例)

实现了一个简单的 HTTP 客户端程序,主要功能是:

  • 读取命令行参数:程序从命令行获取一个或多个 URL。
  • 发送 HTTP GET 请求:使用 Go 内置的 net/http 包,通过 http.Get 函数向每个 URL 发送请求。
  • 读取并输出响应内容:利用 io.ReadAll 读取服务器返回的响应体,将其作为字符串输出到标准输出(屏幕)。
  • 错误处理:如果请求过程中出现错误,程序会在标准错误输出(os.Stderr)中打印错误信息,并以错误状态码退出程序。

这段代码的设计思路与 Unix 下的 curl 工具有相似之处,展示了如何用 Go 编写一个最简单的 HTTP 请求工具。

  1. 包导入

    // Fetch prints the content found at a URL.
    package mainimport ("fmt""io/ioutil""net/http" // 实现了 HTTP 客户端和服务端的基本功能,这里主要用来发起 GET 请求。"os"
    )
    
  2. 程序入口和获取命令行参数

    func main() {for _, url := range os.Args[1:] {// ...}
    }
  3. 发起 HTTP GET 请求

    resp, err := http.Get(url)
    if err != nil {fmt.Fprintf(os.Stderr, "fetch: %v\n", err)os.Exit(1)
    }
    
    • 使用 fmt.Fprintf 将错误信息写入标准错误流,并通过 os.Exit(1) 退出程序,状态码 1 表示出现错误。
  4. 读取响应体

    b, err := io.ReadAll(resp.Body)
    resp.Body.Close()
    if err != nil {fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)os.Exit(1)
    }
    • 服务器返回的响应体是一个流
    • 用io.ReadAll全部读取出来,并存入变量 b 中。
      • b 是由 io.ReadAll 返回的一个 []byte,它用来存储从 resp.Body 中读取到的所有数据。从这个角度看,b 就充当了一个缓冲区,其主要特点和作用如下:
        • 当你调用 io.ReadAll(resp.Body) 时,Go 语言会从网络流(resp.Body)中一次性读取所有数据,并将这些数据存储到一个新的切片 b 中。
        • 这个切片 b 就起到了“缓冲”的作用:它暂时保存了从网络中读取到的数据,方便程序后续操作(比如打印到标准输出)。
        • 为了存储数据,程序必须从操作系统申请一块内存区域,这就是“申请缓冲区”。在这里,io.ReadAll 内部会动态分配足够大小的内存来保存整个响应体的数据。
    • 关闭响应体:调用 resp.Body.Close() 释放与响应相关的资源,防止内存或文件描述符泄露。
    • 很多程序会使用 defer resp.Body.Close() 来确保函数退出时自动关闭流,这也是 Go 中的一个重要惯用法。
      • 在更多场景下推荐使用 defer 来保证资源释放,即使函数中途发生错误也能正确关闭资源。
  5. 输出结果

    fmt.Printf("%s", b)
    

语言特性

  1. 检查错误:Go 语言没有异常机制,而是通过返回值来处理错误。每一步操作(如 HTTP 请求、读取流)都需要检查错误,这种显式的错误处理方式有助于写出健壮的代码。
  2. 资源管理:及时释放资源:读取完响应体后调用 resp.Body.Close() 是非常重要的,防止资源泄露。理解这点对于编写网络或文件 I/O 程序尤为关键。
  3. 标准库的强大支持
    • net/http 包:Go 语言的标准库提供了对 HTTP 的强大支持,不仅能发起请求,还可以构建服务器,这让开发者能快速实现网络应用。
    • io 包:提供了对 I/O 操作的统一抽象,如 io.ReadAll 能简化从流中读取数据的操作。

总结

  1. 这段代码是串行处理每个 URL,但 Go 内置的并发机制(goroutine、channel)可以很方便地改造此程序
  2. 为何在操作结束后需要关闭流(I/O流:文件流,网络流)
    • 操作系统为每个进程分配的文件描述符和网络连接数量是有限的。如果程序中频繁打开流而不关闭,长时间运行后会耗尽这些资源,导致后续无法打开新的文件或建立新的网络连接。
    • 不及时关闭流会导致资源泄露(Resource Leak),即占用的内存和其他系统资源不能被其他部分程序或其他程序使用。这种泄露会降低程序的性能,甚至引发系统崩溃或不稳定。
    • 某些流在写操作时会进行缓冲,如果不调用关闭操作,缓冲区中的数据可能没有及时刷新到磁盘或发送到网络端,可能破坏数据完整性。通过关闭流,系统会自动刷新缓冲区,确保所有数据都已经正确写入或传输。
    • 文件在打开时可能被操作系统或其他程序加锁,防止数据被同时修改。关闭文件流可以释放这些锁定,使其他进程能够正常访问文件,保障系统的安全性和数据的一致性。
  3. 缓冲区
    • 定义:在程序设计中,缓冲区是一个抽象概念,用来描述数据暂存的位置。它帮助平滑数据流的传输,比如在从磁盘读取数据或向网络发送数据时,不必每次都进行低效的逐字节操作,而是先把数据存入缓冲区,再统一处理。

题目

练习 1.7: 函数调用io.Copy(dst, src)会从src中读取内容,并将读到的结果写入到dst中,使用这个函数替代掉例子中的ioutil.ReadAll来拷贝响应结构体到os.Stdout,避免申请一个缓冲区(例子中的b)来存储。记得处理io.Copy返回结果中的错误。

// 使用 io.Copy 将响应体直接写入标准输出,避免申请额外的缓冲区
_, err = io.Copy(os.Stdout, resp.Body)
  • 调用 io.Copy 函数,将数据从 src(这里是 resp.Body)流式复制到 dst(这里是 os.Stdout
    • io.Copy 的工作原理是创建一个固定大小(比如32KB)的缓冲区,在循环中不断地从源(src)读取一块数据,然后立即写入目标(dst)。这样,只需要维持这块缓冲区的内存,而不必为整个数据内容分配一大块连续内存区域。
    • 分块,chunk
  • 对于大文件或长响应数据,直接拷贝可以减少内存占用。流式处理:不需要一次性把所有数据加载到内存中,有助于处理大数据流。

练习 1.8: 修改fetch这个范例,如果输入的url参数没有 http:// 前缀的话,为这个url加上该前缀。你可能会用到strings.HasPrefix这个函数。

  	// 如果 URL 没有 "http://" 前缀,则自动添加if !strings.HasPrefix(url, "http://") {url = "http://" + url}

练习 1.9: 修改fetch打印出HTTP协议的状态码,可以从resp.Status变量得到该状态码。

// 打印出 HTTP 协议的状态码
fmt.Fprintf(os.Stdout, "HTTP status: %s\n", resp.Status)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/32746.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity开发的抖音小游戏接入抖音开放平台中的流量主(抖音小游戏接入广告)

前言:作者在进行小游戏审核版本的过程中,碰到了下列问题,所以对这个抖音小游戏接入广告研究了下。 还有就是作者的TTSDK版本号是6.2.6,使用的Unity版本是Unity2022.3.29f1,最好和作者的两个版本号保持一致,因为我发现TTSDK旧版的很多函数在新版中就已经无法正常使用了,必…

Java高频面试之集合-11

hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝🐶 面试官:详细说说hashmap的put和get操作 HashMap 的 put 和 get 操作是核心功能,其底层通过 数组链表/红黑树 实现&a…

【计算机网络】第八版和第七版的主要区别,附PDF

「《计算机网络》(... 谢希仁」,https://pan.quark.cn/s/7c2147cb48f7 1. 新增内容 - 软件定义网络(SDN):第八版在网络层章节中新增了对SDN的简介(第4章),介绍了其基本原理和应用。 - Wi-Fi代…

批量将 Excel 文档中的图片提取到文件夹

前面我们介绍过如何批量删除 Excel 文档中的所有图片或者指定的图片,其中就需要用到批量提取 Excel 文档中图片的操作。我们如何才能够将 Excel 文档中的图片快速的提取出来呢?其实单个 Excel 文档中的图片提取到文件夹中是有多种方法可以完成的&#xf…

批量删除或替换 Excel 的 Sheet 工作表

在一个 Excel 文档中通常会包含一个或者多个 Sheet 工作表。我们通常也可以自定义的添加或者删除某些工作表。比如我们想要将某个 Excel 的第一个工作表删除,那我们就需要先通过工具打开 Excel 文档,然后再进行删除操作。单个文件我们这样处理是没有问题…

跟踪napi_gro_receive_entry时IP头信息缺失的分析

问题描述 在使用eBPF程序跟踪napi_gro_receive_entry内核跟踪点时,发现获取到的IP头部字段(如saddr、daddr、protocol)为空值。 代码如下: /* 自定义结构体来映射 napi_gro_receive_entry tracepoint 的 format */ struct napi…

【Golang】第五弹----函数

笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:Golang 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 一、函数 1.1基本介绍…

naive ui 控制 n-input 只可以输入26个英文字母+数字

<n-form-item label"编码" path"sn"><n-input v-model:value"form.sn" placeholder"请输入编码" :on-input"handleInput"></n-input></n-form-item> // 处理输入事件的函数 const handleInput (v…

在Pycharm配置conda虚拟环境的Python解释器

〇、前言 今天在配置python解释器时遇到了这样的问题 经过一下午自行摸索、上网搜寻后&#xff0c;终于找到的解决的方案&#xff0c;遂将该方法简要的记录下来&#xff0c;以备后用&#xff0c;并希望能帮助到有同样问题或需求的朋友:) 我所使用的软件的版本如下&#xff0c;假…

网络安全防护架构有哪些 网络安全防护措施包括

网络安全预防措施 网安措施 计算机网络安全措施主要包括保护网络安全、保护应用服务安全和保护系统安全三个方面&#xff0c;各个方面都要结合考虑安全防护的物理安全、防火墙、信息安全、Web安全、媒体安全等等。 (一)保护网络安全。 网络安全是为保护商务各方网络端系统之…

14.C语言const的使用规范,详细说明

目录 修饰变量 修饰指针 指向常量的指针 常量指针 指向常量的常量指针 修饰函数参数 修饰函数返回值 总结 在 C 语言里&#xff0c;const 是一个类型限定符&#xff0c;它的作用是将变量定义为只读&#xff0c;也就是不允许对其值进行修改&#xff0c;用来修饰函数中的…

Android 7 及以上,Fiddler 抓 https 包

文章目录 问题描述解决方案环境准备操作步骤1、导出 Fiddler 证书并修改成 .pem 和 .0 文件2、修改夜神模拟器配置3、打开夜神模拟器设备的 USB 调试选项4、将0725b47c.0证书放入夜神模拟器系统证书目录5、夜神模拟器 cmd 环境配置6、给 0725b47c.0 证书赋予权限7、打开 fiddle…

韦伯望远镜的拉格朗日点计算推导过程,包含MATLAB和python运动轨迹仿真代码

研究过程 起源与提出&#xff1a;1687 年牛顿提出 “三体问题”&#xff0c;旨在研究三个可视为质点的天体在相互之间万有引力作用下的运动规律&#xff0c;但因运动方程过于复杂&#xff0c;难以得到完全解。欧拉的贡献1&#xff1a;1767 年&#xff0c;瑞士数学家莱昂哈德・…

python力扣15. 三数之和

给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 示例 1&am…

【redis】type命令和定时器的两种实现方式(优先级队列、时间轮)

type——返回 key 对应的数据类型 此处 Redis 所有的 key 都是 string&#xff0c;但是 key 对应的 value 可能会存在多种类型 none —— key 不存在string ——字符串list ——列表set ——集合zset ——有序集合hash ——哈希表stream ——Redis 作为消息队列的时候&#x…

游戏引擎学习第153天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾 目前正在进行的是一个比较大的系统调整&#xff0c;原本预计今天会继续深入这个改动&#xff0c;但实际上在昨天的开发中&#xff0c;我们已经完成了大部分的代码编写&#xff0c;并且运行之后几乎一切都能正常工作&#x…

mac 苍穹外卖 前端环境配置

博主的 mac 是 m2。 结合以下两篇&#xff0c;成功配置前端环境。 macOS 配置苍穹外卖前端环境_macbook怎么nginx下载外卖-CSDN博客 苍穹外卖-Mac配置前端开发环境_sudo 启动 nginx 有什么区别-CSDN博客 一、安装nginx 我使用的是 homebrew&#xff0c;homebrew 的安装请自…

Linux——Shell运行原理以及Linux权限

目录 1. Shell的运行原理 2. Linux中的权限问题 2.1 Linux权限的概念 2.1.1 如何实现用户账号之间的切换 2.1.2 如何将普通用户添加到信任列表中 2.1.3 如何仅提升当前指令的权限 2.2 Linux权限管理 2.2.1 文件访问者的分类&#xff08;人&#xff09; 2.2.2 文件类型…

Docker 运行 GPUStack 的详细教程

GPUStack GPUStack 是一个用于运行 AI 模型的开源 GPU 集群管理器。它具有广泛的硬件兼容性&#xff0c;支持多种品牌的 GPU&#xff0c;并能在 Apple MacBook、Windows PC 和 Linux 服务器上运行。GPUStack 支持各种 AI 模型&#xff0c;包括大型语言模型&#xff08;LLMs&am…

2024年广州市智能网联汽车创新实践年度报告

政策法规方面&#xff0c;积极推进《广州市智能网联汽车创新发展条例》的制定和发布&#xff0c;不断完善法规标准体系&#xff0c;为产业创新发展营造良好政策环境&#xff1b;技术创新方面&#xff0c;企业加大研发投入&#xff0c;在自动驾驶算法、车联网安全等关键领域取得…