Golang之实战篇(1)

news2024/11/17 4:42:08

"千篇一律,高手寂寞。几十不惑,全都白扯"

上篇介绍了golang这门新的语言的一些语法。那么我们能用golang简单地写些什么代码出来呢?

一、猜数字

这个游戏的逻辑很简单。系统随机给你生成一个数,然后读取你猜的数字,再根据你猜的数字 跟系统生成的数字比较。告诉你结果这样。

(1)随机生成一个数

随机生成一个区间在1~100之间的数。

import math/rand
import time
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    maxNum := 100
    rand.Seed(time.Now().UnixNano())
    secretNum := rand.Intn(maxNum)
    fmt.Println("The secert number is:", secretNum)
}

用C\C++写过类似程序的朋友们,都会知道使用rand 的时候,如果不设置rand种子,那么生成的随机数是固定的。因此,我们import time,用time中的时间戳,设置rand的种子。

(2)获取用户输入的值

生成要猜的数字是第一步,那么接下来要进行的就是获取用户输入的值。在go中有两个解法

fmt.Scanf;

这个fmt.Scanf的使用和C中的scanf相差无几。也是最简单的获取值的方式。

bufio\os;

bufio:
Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer object, creating another object (Reader or Writer) that also implements the interface but provides buffering and some help for textual I/O.

bufio包实现IO缓冲。它包装了一个可读或者可写的io对象,并创建一个另一个实现接口的对象,为文本文件提供帮助和缓冲

如果有一定的linux系统的知识,对"linux下一切皆文件"这句话不陌生。在linux系统看来,我们的显示器是文件。程序获取用户的数据,是从键盘输入回显到显示器,再从显示器中拿到的。

os:
Package os provides a platform-independent interface to operating system functionality. The design is Unix-like, although the error handling is Go-like; failing calls return values of type error rather than error numbers. Often, more information is available within the error. For example, if a call that takes a file name fails, such as Open or Stat, the error will include the failing file name when printed and will be of type *PathError, which may be unpacked for more information.

简单来说,这个包是提供给用户,独立地操作系统功能的接口。

将从显示器的文件数据,创建另一个对象(reader)管理

reader提供了ReadString的API接口。我试试看

我们通过readString函数,把reader中的值给input。但是这个值不是很干净! 因为有"\r\n"。这个的存在是因为我们敲击了回车!为此,我们需要将input末尾的后缀给干掉!

我们使用strings包里面TrimSuffix的这个函数,顾名思义,是一个过滤后缀的函数。

(3)游戏逻辑判断

打印到显示器上的字符,到底是数字还是字符串?答案是字符串!我们得到的input的值,其实是一段自子串。因此,我们用到如TrimSuffix函数 是针对字符串类型的,而字符串的大小比较 和 整数的大小比较是不一样的!

strconv;

package strconv implements conversions to and from string representations of basic data types
包strconv实现基本数据类型的字符串表示形式之间的相互转换。

后面判断的逻辑也比较简单。也就不多言了。

(4)测试

package main

import (
    "fmt"
    "math/rand"
    "time"

    //系统接口
    "bufio"
    "os"

    //strings操作
    "strconv"
    "strings"
)

func main() {
    maxNum := 100
    rand.Seed(time.Now().UnixNano())
    secretNum := rand.Intn(maxNum)
    fmt.Println("The secert number is:", secretNum)

    for {
        fmt.Println("Please Enter your guess~ ")
        // input := 0
        // fmt.Scanf("%d", &input)
        // fmt.Println(input)

        reader := bufio.NewReader(os.Stdin)
        //拆解
        input, err := reader.ReadString('\n')
        if err != nil {
            fmt.Println("An input Error,Please reinput again", err)
            return
        }
        //fmt.Printf("Befor:%#v\n", input)
        input = strings.TrimSuffix(input, "\n")
        input = strings.TrimSuffix(input, "\r")
        //fmt.Printf("After:%#v\n", input)
        guess, err := strconv.Atoi(input)
        if err != nil {
            fmt.Println("Invalid input,Please Enter your guess again~", err)
            return
        }
        fmt.Println("Your guess is", guess)

        //逻辑判断
        if guess > secretNum {
            fmt.Println("More bigger")
        } else if guess < secretNum {
            fmt.Println("Less smaller")
        } else {
            fmt.Println("You are preety good,and correct: ", secretNum)
            break
        }
    }
}

二、在线词典

我们准备通过http,得到一个英文单词的翻译。

大概是这样的格式。那么制作这个肯定需要一定的网络基础。

(1)处理请求

main;

我们通过命令行,上传我们的请求。这里又要使用到我们的"老朋友" ——os package

JSON;

JSON是一种轻量级的数据交换格式。它采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
//请求报头
type DictRequest struct{
    TransType string `json:"trans_type"`
    Source string `json:"source"`
    UserID string `json:"user_id"`
}

有了请求报头,接下来就需要应对对端返回的json数据应该如何解析。对于js/python这些脚本语言,有字典、map的概念,可以直接从json里面取值。但是对golang是不行的。需要golang创建一个结构体作为解析时的填充对象。

网上有这样结构体代码的生成工具,要我们自己写肯定很麻烦。

type DictResponse struct {
    Rc   int `json:"rc"`
    Wiki struct {
        KnownInLaguages int `json:"known_in_laguages"`
        Description     struct {
            Source string      `json:"source"`
            Target interface{} `json:"target"`
        } `json:"description"`
        ID   string `json:"id"`
        Item struct {
            Source string `json:"source"`
            Target string `json:"target"`
        } `json:"item"`
        ImageURL  string `json:"image_url"`
        IsSubject string `json:"is_subject"`
        Sitelink  string `json:"sitelink"`
    } `json:"wiki"`
    Dictionary struct {
        Prons struct {
            EnUs string `json:"en-us"`
            En   string `json:"en"`
        } `json:"prons"`
        Explanations []string      `json:"explanations"`
        Synonym      []string      `json:"synonym"`
        Antonym      []string      `json:"antonym"`
        WqxExample   [][]string    `json:"wqx_example"`
        Entry        string        `json:"entry"`
        Type         string        `json:"type"`
        Related      []interface{} `json:"related"`
        Source       string        `json:"source"`
    } `json:"dictionary"`
}

这样我们就得到了JSON结构体。解析http返回的报头。

net/http;

Package http provides HTTP client and server implementations.
包http提供了HTTP客户端和服务器实现。

client是http中的一个对象

Marshal;

bytes;

Package bytes implements functions for the manipulation of byte slices. It is analogous to the facilities of the strings package.

实现了操作子串切片的操作。类似字符串包strings的功能

(2)处理响应

发送一个http请求,并返回一个http响应。

而此时我们响应数据全在resp中。我们需要的是响应数据中的正文部分。

ioutil;

Package util contains utility code for use by volume plugins.

这个包提供一些好用的工具

但是,我们此时拿到的正文数据,是JSON格式的。我们为此需要将次填入我们为JSON事先创建好的结构体中。这个过程叫做,反序列化。

我们也就拿到返回的数据内容了。

(3)数据解析

我们来看看效果吧~

三、SOCKET5代理

(1)代理服务器简介

代理服务器(Proxy Server)的功能是代理网络用户去取得网络信息。形象地说,它是网络信息的中转站,是个人网络和Internet服务商之间的中间代理机构,负责转发合法的网络信息,对转发进行控制和登记。

取自这里

SOCKS5 是一个代理协议,它在使用TCP/IP通讯的前端机器和服务器机器之间扮演一个中介角色,使得 内部网 中的前端机器变得能够访问Internet网中的服务器,或者使通讯更加安全。SOCKS5 服务器通过将前端发来的请求转发给真正的目标服务器, 模拟了一个前端的行为。在这里,前端和SOCKS5之间也是通过 TCP/IP协议 进行通讯,前端将原本要发送给真正服务器的请求发送给SOCKS5服务器,然后SOCKS5服务器将请求转发给真正的服务器。
SOCKS5虽然是代理服务协议,但是不用作"翻墙",它的协议是明文传输。

取自这里

(2)SOCKS5原理

(3)建立TCP

package main

import (
    "log"
    "net"
)

func main() {
    server, err := net.Listen("tcp", "127.0.0.1:8801")
    if err != nil {
        log.Fatal(err)
    }

    for {
        client, err := server.Accept()
        if err != nil {
            log.Printf("Accept faild:%v", err)
            //没有链接到来持续等待即可
            continue
        }

        //连接到来
        go proceess(client)
    }
}

func proceess(conn net.Conn) {

}
goroutinue 可以类比一个进程里的子进程,但是开销小很多。

Process;

func proceess(conn net.Conn) {
    defer conn.Close()
    reader := bufio.NewReader(conn)
    for {
        b, err := reader.ReadByte()
        if err != nil {
            break
        }

        _, err = conn.Write([]byte{b})
        if err != nil {
            break
        }
    }
}

defer这一行的含义,就是在函数结束时,释放掉资源。防止资源泄漏

接下来我们使用的bufio。我们在猜数字的时候用过。它为可读或可写的对象提供一个缓冲区。这里的IO输出是针对网络套接字,但是IO的速度是很慢的。因此,我们把网络数据 转换为bufio的形式,减少底层系统调用,同时,bufio也会提供一定的工具帮我们对数据进行获取。

这里conn底层回去调用Write。conn保存了系统为这个连接打开的fd。

(4)认证阶段

代理服务器不仅仅是获取数据即可。否则我们刚刚完成一个TCP连接即可。

认证时,浏览器会发三个字段给代理服务器:version、methods、methods编码

version;

method;

它返回复制的字节数,如果读取的字节数较少,则返回一个错误。

这样我们也就获取了version与method;此时,代理服务器需要向 浏览器返回两个字段,version\method;

(5)请求阶段

在这个阶段,我们就需要拿到浏览器url里面访问的IP+PORT,定位服务器。此时我们增加了一个connect函数帮我们完成这个功能

atyp地址类别;

如果是IPV4,我们逐个将这刚好4字节打印成IP地址的格式。

如果是host,我们则需要重新计算大小,转换成字符串并保存。

IPV6这里算了。用得少。

端口port;

我们日常生活中的有大端机,小端机。所谓大小端机最大的差别,就在于存储字符的字节序不同。为了屏蔽掉这个差异,网络中统一发送的字节序为大端字节序。如果是小端机接收,那么你就需要进行转换,如果是大端,那就什么都可以不做。

(6)Relay阶段

此时两端主机正式开始建立连接了。

但是有个问题是,一旦执行到这里,connect函数就会结束。那么两个端的连接也就会被关闭。因此,什么时候应该是将两端连接关闭呢? 一旦其中一方出现copy错误时~

context;

Package context defines the Context type, which carries deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes.

包上下文定义了上下文类型,它携带截止日期、取消信号和其他跨API边界和进程间的请求范围的值。

当调用cancel()的时候, 处于等待的ctx.Done()会立即返回。

以上也就简简单单用golang做了一些小的代码。

感谢你的阅读,

祝你好运,向阳而生~

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

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

相关文章

老杨说运维 | AIOps如何助力实现全面可观测性(上)

前言&#xff1a; 嗨&#xff0c;今天是大年三十&#xff0c;大家是不是已经在家坐享团圆之乐了&#xff1f;还是说在奔向团圆的路上呢&#xff1f;不论如何&#xff0c;小编先祝大家新年如意安康&#xff0c;平安顺遂~ 熟悉我们的朋友肯定都知道&#xff0c;关于《老杨说运维…

30.字符串处理函数

文章目录1.测字符串长度函数2.字符串拷贝函数1.strcpy函数2.strncpy函数3.字符串追加函数1.strcat函数2.strncat函数4.字符串比较函数1.strcmp函数2.strncmp函数5.字符查找函数1.strchr函数2.strrchr函数6.字符串匹配函数7.空间设定函数8.字符串转换数值9.字符串切割函数strtok…

【Java开发】Spring Cloud 04 :服务治理Nacos

本章节正式进入 Spring Cloud 环节了&#xff0c;首先介绍微服务架构中一个最重要的原理概念&#xff1a;服务治理&#xff0c;在概念讲解之后&#xff0c;讲解介绍 Nacos 服务注册中心的体系结构。1 服务治理1.1 服务治理介绍首先通过一个例子告诉你服务治理解决了什么问题。比…

GD32F4——外部中断

一、NVIC中断系统 Cortex-M4集成了嵌套式矢量型中断控制器&#xff08;Nested Vectored Interrupt Controller&#xff0c;NVIC&#xff09;来实现高效的异常和中断处理。 中断系统包含外部中断、定时器中断、DMA中断和串口中断等。 二、EXTI外部中断 EXTI&#xff08;中断…

go的基本语法介绍之变量的声明与初始化

1.常见基本数据类型 uint8&#xff1a;无符号8位整形&#xff0c;取值范围&#xff1a;0-255 uint16&#xff1a;无符号16位整形&#xff0c;取值范围&#xff1a;0-65535 uint32&#xff1a;无符号32位整形&#xff0c;取值范围&#xff1a;0-4294967295 uint64&#xff1…

opencv arm交叉编译与仿真验证详细流程

【关键内容】 1.将opencv编译为能在arm上运行的库 2.在没有板子的情况下&#xff0c;仿真验证opencv库 1.将opencv编译为能在arm上运行的库 1.在下方链接中选择某个版本 Releases - OpenCVhttps://opencv.org/releases/点击“Sources”即可开始下载&#xff0c;得到opencv-…

「数据结构、逻辑结构、物理结构」基本概念简析

前言 前言&#xff1a;简析数据结构、逻辑结构、物理结构。 文章目录前言一、数据结构1. 简介2. 数据3. 结构4. 分析5. 分类1&#xff09;线性结构&#xff08;线性表&#xff09;2&#xff09;树结构3&#xff09;图结构二、逻辑结构与物理结构1. 为什么要有逻辑结构和物理结构…

【leetcode合集】如何知道自己是否掌握了数组与链表?试试这几道题目吧!

目录 1.数组题目合集 1.1 leetcode.27 移除元素 1.2 leetcode.26 删除有序数组中的重复项 1.3 leetcode.88 合并两个有数数组 2.链表题目合集 2.1 leetcode.203 移除链表元素 2.2 leetcode.206 反转链表 2.3 leetcode.876 链表的中间结点 2.4 牛客 链表中倒数第k个结点…

零基础学JavaWeb开发(十七)之 mybatis(2)

5、MyBatis - 映射文件标签 5.1、映射文件的顶级元素 select&#xff1a;映射查询语句 insert&#xff1a;映射插入语句 update&#xff1a;映射更新语句 delete&#xff1a;映射删除语句 sql&#xff1a;可以重用的 sql 代码块 resultMap&#xff1a;最复杂&#xff0c…

章鱼网络 2022 虎年全回顾

全长5606字&#xff0c;预计阅读20分钟2022年对章鱼网络而言颇为特别。这是章鱼网络建设应用链多链生态历程的第一年&#xff0c;整个 Web3 行业都经历了极其糟糕的市场环境&#xff0c;但是我们在「生态建设」、「基础设施优化」、「社区治理」和「市场拓展」等都有长足进展&a…

31.Isaac教程--规划器代价

规划器代价 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录规划器代价组件入门通过应用程序图自定义成本导航本地规划器基于线性二次调节器 (LQR) 规划器。 它通过生成最小化成本函数的轨迹来工作。 不幸的是&#xff0c;没有适用于所有…

Allegro如何输出第三方网表操作指导

Allegro如何输出第三方网表操作指导 在做PCB设计的时候,会需要输第三方网表,Allegro支持快速输出第三方网表,如下图 具体操作如下 选择File选择Export

Leetcode:39. 组合总和、40. 组合总和 II(C++)

目录 39. 组合总和&#xff1a; 问题描述&#xff1a; 实现代码与解析&#xff1a; 回溯&#xff1a; 原理思路&#xff1a; 剪枝版&#xff1a; 40. 组合总和 II&#xff1a; 问题描述&#xff1a; 实现代码与解析&#xff1a; 回溯&#xff1a; 原理思路&#xff…

函数——“C”

各位CSDN的uu们新年快乐呀&#xff0c;祝大家越来越开心&#xff0c;越来越优秀。那行&#xff0c;让我们进入今天的正题&#xff0c;来了解了解函数&#xff0c;函数是什么&#xff0c;C语言中函数是如何分类的&#xff0c;函数参数&#xff0c;函数调用等一系列小知识点&…

文件操作详解-IO

目录 1.认识文件 2.文件的类型 3.java对文件的操作 针对文件系统操作 针对文件内容操作 字节流 字符流 字节流的使用 字符流的使用 4.文件IO小程序练习 示例1 示例2 1.认识文件 狭义的文件指的是硬盘上的文件和目录 广义的文件泛指计算机中的很多的软硬件资源,操…

3小时精通opencv(二)图片的常用操作

3小时精通opencv(二)图片的常用操作 参考视频资源:3h精通Opencv-Python 文章目录3小时精通opencv(二)图片的常用操作灰度图像高斯滤波边缘检测膨胀函数腐蚀函数整体代码灰度图像 img cv2.imread(Resources/lena.png) imgGray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.im…

【C++】位图 | 布隆过滤器

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;哈希函数…

添加选课模块分析

1 模块需求分析 1.1 模块介绍 本模块实现了学生选课、下单支付、学习的整体流程。 网站的课程有免费和收费两种&#xff0c;对于免费课程学生选课后可直接学习&#xff0c;对于收费课程学生需要下单且支付成功方可选课、学习。 选课&#xff1a;是将课程加入我的课程表的过…

论文投稿指南——中文核心期刊推荐(水利工程)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

大展宏图、首创基于.NET 7强大内核-Zoomla!逐浪CMS v8.7.0发布

2022年底&#xff0c;微软 .NET Conf 在线活动正式开幕。作为微软开源、跨平台开发平台&#xff0c;.NET 7 现已推出首个正式版&#xff0c;这也代表微软的“统一工作”终于完成。 使用 .NET 7 可以轻松地将 .NET 7 项目容器化&#xff0c;在 GitHub 操作中设置 CI / CD 工作流…