【Go语言快速上手(六)】管道, 网络编程,反射,用法讲解

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:Go语言专栏⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习更多Go语言知识
  🔝🔝


在这里插入图片描述

GO快速上手

  • 1. 前言
  • 2. 初识管道
  • 3. 管道的高级用法
  • 4. GO中的网络编程
  • 5. GO语言中的反射
  • 6. 总结以及拓展

1. 前言

本篇文章是GO语言快速上手系列的最后一篇文章, 学完本章后你就掌握了GO语言常用的所有知识和语法, 在未来使用GO语言时你可能还会遇见一些奇怪的语法,但是别害怕, GO就是为了简洁而生,你有Java或CPP的基础,学什么都很快的

本章重点:

本篇文章着重讲解GO中的管道的概念以及用法. 还会讲解GO语言是怎样实现网络编程的, 会通过一个例子来讲解. 最后会讲解GO语言的反射机制,以及反射的语法.由于GO语言没有传统意义上的泛型编程概念,所以学习反射还是有必要的


2. 初识管道

说白了管道就是一个数据结构: 队列

在这里插入图片描述

管道的定义:

var 变量名 chan 管道类型
var channel chan int
管道可通过make进行初始化
channel = make(chan int,3)//管道可以存放三个int类型变量

管道是有类型的,int类型管道只能写入int类型数据,并且管道是引用类型,必须初始化后,即make后才能使用它.除此之外,管道的用法比较奇特,通过左箭头<-来向管道存放或取出数据

var intchan chan int = make(chan int,3)
//向管道中存放数据
intchan<-10
intchan<-20
num := 30
intchan<-num
//从管道中取出数据
data1 := <-intchan
data2 := <-intchan
data3 := <-intchan

显而易见,插入管道的顺序为10,20,30,所以取出数据时,data123分别对应10,20,30. 并且从管道中取出数据的意思就是把它拿出来. 除此之外,使用范围for进行遍历时,打印出数据后, 管道中的数据也会被取出.

var intchan chan int = make(chan int,3)
//向管道中存放数据
intchan<-10
intchan<-20
num := 30
intchan<-num
for v:= range intchan{fmt.Println("value: ",v)
}

管道的for-range循环只有value,没有key,并且如果你直接这样写代码,会报错, 因为for-range会一直遍历管道,并不会在乎管道中是否还存在数据. 所以在使用for-range之前应该先用close函数将管道关闭

  • 不关闭管道, for-range会一直取数据
  • 关闭管道后, 不可写入,但可读取

3. 管道的高级用法

管道可以声明为只读或只写性质:

var intchan1 chan<- int //只写
var intchan2 <-chan int //只读

除此之外,如果你学过多路转接select,那么这对于你来说应该很轻松.当有多个管道时,需要解决选择问题,select的作用就是在多个管道中随机公平的选择一个来执行.这是通过select和case来实的,case后面必须进行IO操作,不能是等值, 随机去选取一个IO操作.若select时迟迟没有管道就绪,那么就会一直阻塞在select处.加上default语句,可以避免这种阻塞发生

package mainimport ("fmt""time"
)
func main() {intchan1 := make(chan int, 10)intchan2 := make(chan string, 10)intchan3 := make(chan float32, 10)go func() {//匿名函数time.Sleep(time.Second * 5)intchan1 <- 10}()go func() {time.Sleep(time.Second * 4)intchan2 <- "zbcdefg"}()go func() {time.Sleep(time.Second * 3)intchan3 <- 3.14}()select {case v1 := <-intchan1:fmt.Printf("intchan1: %v", v1)case v2 := <-intchan2:fmt.Printf("intchan2: %v", v2)case v3 := <-intchan3:fmt.Printf("intchan3: %v", v3)default:fmt.Println("防止select被阻塞")}
}

在这里插入图片描述


4. GO中的网络编程

GO语言有net包直接进行网络编程,十分的方便,不像CPP一样进行网络编程时需要调用系统调用来完成.话不多说,直接上手代码示例:

服务器端:

  1. 监听一个地址和端口

  2. 接受客户端的连接

  3. 读取和写入数据

package main  
import (  "bufio"  "fmt"  "net"  "os"  
)  
func main() {  // 监听TCP端口  listener, err := net.Listen("tcp", ":8080")  if err != nil {  fmt.Println(err)  return  }  defer listener.Close()  for {  // 接受新的连接  conn, err := listener.Accept()  if err != nil {  fmt.Println(err)  continue  }  //到来连接时,让协程去执行读写操作go handleRequest(conn) // 使用goroutine处理连接  }  
}  func handleRequest(conn net.Conn) {  defer conn.Close()  // 读取数据  reader := bufio.NewReader(conn)  message, err := reader.ReadString('\n')  if err != nil {  fmt.Println(err)  return  }  fmt.Print("Message received: ", string(message))  // 发送数据  conn.Write([]byte("Message received!\n"))  
}

如果你清楚TCP通信的基本流程,那么你一定知道,net.Listen函数就是封装了系统调用listen,而方法listener.Accept封装了系统调用accept,返回的conn也就是就绪的连接fd

客户端:

  1. 连接到服务器

  2. 读取和写入数据

package main  
import (  "bufio"  "fmt"  "net"  "os"  
)  
func main() {  // 连接到TCP服务器  conn, err := net.Dial("tcp", "127.0.0.1:8080")  if err != nil {  fmt.Println(err)  return  }  defer conn.Close()  // 发送数据  fmt.Fprintf(conn, "Hello, Server!\n")  // 读取响应  reader := bufio.NewReader(conn)  message, err := reader.ReadString('\n')  if err != nil {  fmt.Println(err)  return  }  fmt.Print("Message from server: ", string(message))  
}

对Linux熟悉的同学一眼就能看出,这个fprintf就是向文件描述符conn中输入数据的,都是封装了C,所以说我建议学GO语言要先把基础知识打牢固


5. GO语言中的反射

GO不直接支持泛型编程,但通过反射可以弥补这一缺陷,话不多说,直接上概念:

在这里插入图片描述
代码示例:

func test(i interface{}){//1.调用typeof函数,返回reflect.Type类型数据reType := reflect.TypeOf(i)fmt.Println(reType)//2. 调用valueof函数,返回reflect.value类型数据reValue := reflect.ValueOf(i)fmt.Println(reValue)//注,revalue是valueof类型,不能直接进行运算//想要获取revalue的值要调用revalue.Int()方法
}func main(){//对基本类型进行反射var num int = 100test(num)
}

反射要通过传递空接口来实现,不知各位是否还记得在讲接口时说到,任意类型都实现的空接口,也就是说任意类型的变量都可以传递给空接口,接口和reflect.value类型可以相互转换,转换关系如下:

在这里插入图片描述

获取变量的类别有两种方式:

reflect.Type.kind()
reflect.Value.kind()

注意,类别和类型是两种概念,类别是指bool,int,int32,int64,struct,map这种大分类,而变量的类型是小分类. 除此之外,还可以对结构体类型进行反射:

func test(i interface{}){//1.调用typeof函数,返回reflect.Type类型数据reType := reflect.TypeOf(i)fmt.Println(reType)//2. 调用valueof函数,返回reflect.value类型数据reValue := reflect.ValueOf(i)fmt.Println(reValue)fmt.Println(reType.kind())
}type stu struct{Name stringAge int
}func main(){//对结构体类型进行反射student := stu{Name : "张三"Age : 18}test(student)
}

在这里插入图片描述

更多关于反射的使用手册,大家可以自行问GPT


6. 总结以及拓展

GO语言快速上手这一系列的文章就结束了,但GO语言的学习之旅还远远没有结束, 本系统文章只讲解了很常用的GO语法,在实际生产生活中,如果遇见了诸如像context类型的新概念,大家可以自行去学习,感谢您的阅读,再见

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

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

相关文章

清新优雅、功能强大的后台管理模板 | 开源日报 No.238

soybeanjs/soybean-admin Stars: 7.0k License: MIT soybean-admin 是一个基于 Vue3、Vite5、TypeScript、Pinia、NaiveUI 和 UnoCSS 的清新优雅且功能强大的后台管理模板。 使用最新流行的技术栈&#xff0c;如 Vue3、Vite5 和 TypeScript。采用清晰的项目架构&#xff0c;易…

Mac M2 本地下载 Xinference

想要在Mac M2 上部署一个本地的模型。看到了Xinference 这个工具 一、Xorbits Inference 是什么 Xorbits Inference&#xff08;Xinference&#xff09;是一个性能强大且功能全面的分布式推理框架。可用于大语言模型&#xff08;LLM&#xff09;&#xff0c;语音识别模型&…

Kubernetes 弃用Docker后 Kubelet切换到Containerd

containerd 是一个高级容器运行时&#xff0c;又名 容器管理器。简单来说&#xff0c;它是一个守护进程&#xff0c;在单个主机上管理完整的容器生命周期&#xff1a;创建、启动、停止容器、拉取和存储镜像、配置挂载、网络等。 containerd 旨在轻松嵌入到更大的系统中。Docke…

screen服务使用解析

一、为什么要使用screen服务 当我们在进行一些常见的远程操作时&#xff0c;通常首先会先进行远程ssh登录 或者telnet连接到远程服务器上&#xff0c;然后执行相关操作&#xff0c;或程序启动等。 1、程序所需的执行时间过长&#xff0c;可能需要挂载几天的那种&#xff0c;可…

Linux(ubuntu)—— 用户管理user 用户组group

一、用户 1.1、查看所有用户 cat /etc/passwd 1.2、新增用户 useradd 命令&#xff0c;我这里用的是2.4的命令。 然后&#xff0c;需要设置密码 passwd student 只有root用户才能用passwd命令设置其他用户的密码&#xff0c;普通用户只能够设置自己的密码 二、组 2.1查看…

基于ROS从零开始构建自主移动机器人:仿真和硬件

书籍&#xff1a;Build Autonomous Mobile Robot from Scratch using ROS&#xff1a;Simulation and Hardware 作者&#xff1a;Rajesh Subramanian 出版&#xff1a;Apress 书籍下载-《基于ROS从零开始构建自主移动机器人&#xff1a;仿真和硬件》您将开始理解自主机器人发…

aic8800 linux

编译方法参考 http://t.csdnimg.cn/epR89 aic8800 源码在 github 里。同样需要 cfg80211 和 mac80211 aic_load_fw/aic_load_fw.ko aic8800_fdrv/aic8800_fdrv.ko都放到放 .ko 的地方 src/USB/driver_fw/drivers/aic8800 就是源码&#xff0c;没有蓝牙的型号不需要aic_btusb …

ip地址与硬件地址的区别是什么

在数字世界的浩瀚海洋中&#xff0c;每一台联网的设备都需要一个独特的标识来确保信息的准确传输。这些标识&#xff0c;我们通常称之为IP地址和硬件地址。虽然它们都是用来识别网络设备的&#xff0c;但各自扮演的角色和所处的层次却大相径庭。虎观代理小二将带您深入了解IP地…

6.k8s中的secrets资源

一、Secret secrets资源&#xff0c;类似于configmap资源&#xff0c;只是secrets资源是用来传递重要的信息的&#xff1b; secret资源就是将value的值使用base64编译后传输&#xff0c;当pod引用secret后&#xff0c;k8s会自动将其base64的编码&#xff0c;反编译回正常的字符…

HTTP/1.1、HTTP/2、HTTP/3 的演变

HTTP/1.1、HTTP/2、HTTP/3 的演变 HTTP/1.1 相比 HTTP/1.0 提高了什么性能&#xff1f;HTTP/2 做了什么优化&#xff1f;HTTP/3 做了哪些优化&#xff1f; HTTP/1.1 相比 HTTP/1.0 提高了什么性能&#xff1f; HTTP/1.1 相比 HTTP/1.0 性能上的改进&#xff1a; 使用长连接的…

再生龙clonezilla使用方法

目录 本文相关内容的介绍服务器窗口重定向引导进入再生龙系统检查本机操作系统的引导模式 再生龙基础功能选择选择 device-image选择ssh_server 网络配置ssh_server 配置ssh_server 镜像存储路径 再生龙抓取操作系统抓取镜像的命名 再生龙恢复操作系统拉取镜像的选择 本文相关内…

【16-Ⅰ】Head First Java 学习笔记

HeadFirst Java 本人有C语言基础&#xff0c;通过阅读Java廖雪峰网站&#xff0c;简单速成了java&#xff0c;但对其中一些入门概念有所疏漏&#xff0c;阅读本书以弥补。 第一章 Java入门 第二章 面向对象 第三章 变量 第四章 方法操作实例变量 第五章 程序实战 第六章 Java…

收藏:关于闭包表

参考视频&#xff1a;【IT老齐513】经典树形数据结构-闭包表_哔哩哔哩_bilibili&#xff0c; 这个视频系列的确不错&#xff0c;500多个了。 闭包表&#xff0c;其实就是用来做树形结构的时候&#xff0c;如何快速找到某个节点下的所有后代节点&#xff0c;用两张表去完成&…

机器学习实战-聚类算法

聚类算法是一种无监督学习的算法&#xff0c;用于将数据集中的数据分成不同的聚类或组。聚类算法是数据挖掘和机器学习领域中常见的技术之一&#xff0c;具有广泛的应用。 以下是聚类算法的一些知识点&#xff1a; 聚类算法的目的是将数据集划分为不同的组&#xff0c;使得组内…

C++ 矩阵

目录 了解矩阵的数学原理&#xff08;大学线性代数&#xff09; 矩阵及转置矩阵 矩阵乘法 矩阵快速幂 相伴矩阵模板 [相伴矩阵,快速矩阵幂]CSES1722 Fibonacci Numbers 了解矩阵的数学原理&#xff08;大学线性代数&#xff09; 矩阵及转置矩阵 这里A就是一个矩阵&…

uniapp 桌面应用插件 Ba-Launcher

简介&#xff08;下载地址&#xff09; Ba-Launcher 可以让你的应用成为简单的桌面应用&#xff0c;如需扩展功能&#xff0c;请联系我。 截图展示 可关注博客&#xff0c;实时更新最新插件&#xff1a; uniapp 常用原生插件大全 使用方法 使用方法也很简单&#xff0c;在插…

PG数据库结构与oracle比较

1.数据库集簇逻辑结构 数据库集簇概念&#xff1a;一个大的数据库是由若干个小的数据库组成&#xff0c;实现数据的隔离存放&#xff0c;在概念上应该是与mysql一样的 在mysql中可以用show database列出数据库 PG中用\l 数据库对象存放在数据库中&#xff1a; PG中的所有数据…

计算机英文论文常见错误写作习惯3

目录 第一部分 Numbers and Equations ‘such as’ and ‘etc.’ 第二部分 第一部分 Numbers and Equations 两个非常常见的错误是关于阿拉伯数字和方程式的表示。中国作家通常写阿拉伯数字&#xff0c;而不是拼出单词。然而&#xff0c;使用阿拉伯数字本身并不是一个错误…

简约大气的全屏背景壁纸导航网源码(免费)

简约大气的全屏背景壁纸导航网模板 效果图部分代码领取源码下期更新预报 效果图 部分代码 <!DOCTYPE html> <html lang"zh-CN"> <!--版权归孤独 --> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible…

工厂模式和策略模式区别

工厂模式和策略模式都是面向对象设计模式&#xff0c;但它们的目的和应用场景有所不同。 工厂模式是一种创建型设计模式&#xff0c;旨在通过使用一个工厂类来创建对象&#xff0c;而不是直接使用new关键字来创建对象。这样做可以使系统更容易扩展和维护&#xff0c;因为新的对…