Golang 基础案例集合:中文拼音转换、解析二维码、压缩 zip、执行定时任务

news2024/11/27 5:28:22

前言

曾经,因为不够注重基础吃了好多亏。总是很喜欢去看那些高大上的东西,却忽略了最基本的东西。然后会错误的以为自己懂的很多,但是其实是沙堆中筑高台,知道很多高大上的架构,但是基础的东西却不太了解。我觉得,可能这就是大部分开发工程师的通病吧。

所以,深入一门语言,也不用一直看重多高端、高大上的框架功能服务,尝试一下小案例,拓宽一下对于语言的更深层次的理解。

文章目录

    • 前言
    • 基础案例
      • 中文拼音转换
      • 解析二维码
      • 压缩文件成 zip
      • 执行定时任务
        • 自带原始库
        • 定时任务库选择
    • 总结

基础案例

  • 中文拼音转换:根据用户名快速创建个人 id
  • 解析二维码:帮助快速识别硬件码
  • 压缩 zip:压缩文件,便于传输数据
  • 执行定时任务:方便自动化操作

中文拼音转换

package main

import (
	"fmt"
	"github.com/mozillazg/go-pinyin"
)

func main() {
	hans := "中国人"

	// 默认
	a := pinyin.NewArgs()
	fmt.Println(pinyin.Pinyin(hans, a))
	// [[zhong] [guo] [ren]]

	// 包含声调
	a.Style = pinyin.Tone
	fmt.Println(pinyin.Pinyin(hans, a))
	// [[zhōng] [guó] [rén]]

	// 声调用数字表示
	a.Style = pinyin.Tone2
	fmt.Println(pinyin.Pinyin(hans, a))
	// [[zho1ng] [guo2] [re2n]]

	// 开启多音字模式
	a = pinyin.NewArgs()
	a.Heteronym = true
	fmt.Println(pinyin.Pinyin(hans, a))
	// [[zhong zhong] [guo] [ren]]
	a.Style = pinyin.Tone2
	fmt.Println(pinyin.Pinyin(hans, a))
	// [[zho1ng zho4ng] [guo2] [re2n]]

	fmt.Println(pinyin.LazyPinyin(hans, pinyin.NewArgs()))
	// [zhong guo ren]

	fmt.Println(pinyin.Convert(hans, nil))
	// [[zhong] [guo] [ren]]

	fmt.Println(pinyin.LazyConvert(hans, nil))
	// [zhong guo ren]
}

实际应用过程中,只要能够获取需要转换的中文词语字符串数组即可实现中文拼音转换的操作,不过,虽然使用的包 github.com/Chain-Zhang/pinyin 相对于其他 golang 拼音转换项目的资料多一点,但貌似不维护了。

package main

import (
	"fmt"
	"github.com/mozillazg/go-pinyin"
	"strings"
	"reflect"
	"github.com/astaxie/beego"
)

func main() {
	hans := "中国人"

	a := pinyin.LazyConvert(hans, nil)
	// [zhong guo ren]

	var test []string = []string{}
	for a, v := range a{
		beego.Info(v)
		beego.Info(a)
		if a == 0 {
			test = append(test, v)
		} else {
			test = append(test, ",")
			test = append(test, v)
		}

	}
        beego.Info("处理1")
	beego.Info(test)

//  通过这一条处理 strings.Trim
	result := strings.Trim(fmt.Sprint(test), "[]")
	// result := strings.Replace(strings.Trim(fmt.Sprint(test), "[]"), " ", ",", -1)
	beego.Info(result)
	beego.Info(reflect.TypeOf(result))

result2 := strings.Replace(result, " , ", "", -1)
       beego.Info(result2)
	// zhongguoren
}

运行代码如下:

go get -u github.com/mozillazg/go-pinyin
go run main.go

可得以下结果:
中文转拼音结果

解析二维码

思路:

  1. 上传图片或者本地读取图片
  2. 将文件流写入到gozxing 的函数中解析二维码
    这里采用上传文件的形式,如下:
package main

import (
	"fmt"
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"github.com/makiuchi-d/gozxing"
	"github.com/makiuchi-d/gozxing/qrcode"
	"github.com/gin-gonic/gin"
	"net/http"
	"io"
)

func main() {
	router := gin.Default()
	router.POST("/upload", func(c *gin.Context) {
		// The default memory allocation is 10M
		file, err := c.FormFile("filename")
		if err != nil {
			c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
			return
		}

		//文件大小限制
		if file.Size > (10 << 20) {
			c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", "文件太大,请重新上传"))
			return
		}

		c.String(http.StatusOK, fmt.Sprintf("File %s uploaded success", file.Filename))
		//fmt.Println(file.Filename, "文件名")
		fi, err := file.Open()
		if err != nil {
			fmt.Println(err)
		}
		defer fi.Close()

		str := GetPaymentStr(fi).String()
		fmt.Println("qrcode_url:", str)
	})
	router.Run(":8000")
}

func GetPaymentStr(fi io.Reader) (paymentCodeUrl *gozxing.Result) {
	img, _, err := image.Decode(fi)
	if err != nil {
		fmt.Println(err)
	}
	// prepare BinaryBitmap
	bmp, _ := gozxing.NewBinaryBitmapFromImage(img)
	// decode image
	qrReader := qrcode.NewQRCodeReader()
	result, err := qrReader.Decode(bmp, nil)
	if err != nil {
		fmt.Println(err)
	}

	return result
}

注意使用的图片格式包,需要哪种格式,才导入哪种格式,剔除冗余文件。

图片文件格式选择
注意关闭文件流哦!

关闭流
图片拷贝不如,基本就要再读写一次,不如同时开两个流
流的使用

压缩文件成 zip

在软件很多应用开发过程中,经常需要使用到文件压缩。有时候是为了加快存盘速度,有时候是为了节省硬盘空间,有时候是为了提高传输效率。gzip是一种比较通用的压缩程序,golang系统自带的包里边compress/gzip就可以实现在代码中实现gzip的功能。

定义解压缩文件接口CompressFile和DeCompressFile:
gziptest.go:

package gziptest

import (
    "compress/gzip"
    "io"
    "os"
)

//压缩文件Src到Dst
func CompressFile(Dst string, Src string) error {
    newfile, err := os.Create(Dst)
    if err != nil {
        return err
    }
    defer newfile.Close()

    file, err := os.Open(Src)
    if err != nil {
        return err
    }

    zw := gzip.NewWriter(newfile)

    filestat, err := file.Stat()
    if err != nil {
        return nil
    }

    zw.Name = filestat.Name()
    zw.ModTime = filestat.ModTime()
    _, err = io.Copy(zw, file)
    if err != nil {
        return nil
    }

    zw.Flush()
    if err := zw.Close(); err != nil {
        return nil
    }
    return nil
}

//解压文件Src到Dst
func DeCompressFile(Dst string, Src string) error {
    file, err := os.Open(Src)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    newfile, err := os.Create(Dst)
    if err != nil {
        panic(err)
    }
    defer newfile.Close()

    zr, err := gzip.NewReader(file)
    if err != nil {
        panic(err)
    }

    filestat, err := file.Stat()
    if err != nil {
        panic(err)
    }

    zr.Name = filestat.Name()
    zr.ModTime = filestat.ModTime()
    _, err = io.Copy(newfile, zr)
    if err != nil {
        panic(err)
    }

    if err := zr.Close(); err != nil {
        panic(err)
    }
    return nil
}

单元测试用例(调用函数):
gziptest_test.go:


package gziptest

import (
    "os"
    "testing"
)

func TestCompressFile(t *testing.T) {
    pwd, _ := os.Getwd()
    newfile, err := os.Create(pwd + "/test.txt")
    if err != nil {
        t.Fatal(err)
    }
    newfile.Write([]byte("hello world!!!!"))
    newfile.Close()

    err = CompressFile(pwd+"/test.gz", pwd+"/test.txt")
    if err != nil {
        t.Fatal(err)
    }
}

func TestDeCompressFile(t *testing.T) {
    pwd, _ := os.Getwd()

    err := DeCompressFile(pwd+"/test2.txt", pwd+"/test.gz")
    if err != nil {
        t.Fatal(err)
    }
}

测试结果:

C:/Go/bin/go.exe test -v [D:/go/src/gziptest]
=== RUN   TestCompressFile
--- PASS: TestCompressFile (0.00s)
=== RUN   TestDeCompressFile
--- PASS: TestDeCompressFile (0.00s)
PASS
ok      gziptest    2.351s

同级目录下增加了三个文件:

  • test.txt
  • text2.txt
  • text.gz
    其中test.txt和test2.txt内容为:
hello world!!!!
1

test.gz内容为text.txt

执行定时任务

golang中需要定时执行某些任务,完成一些自动化操作。

自带原始库


func DocSyncTaskCronJob() {
	ticker := time.NewTicker(time.Minute * 1) // 每分钟执行一次
	for range ticker.C {
		ProcTask()
	}
}

func ProcTask() {
	log.Println("hello world")
}

调研一下后发现Golang并没有十分完善的定时任务库。无法完成复杂的定时任务。

  • 事件订阅/通知机制不成熟
  • 无法适用于更灵活的场景,例如多节点的分布式任务调度执行
  • 模块之间的职责不清晰,例如其实Timer模块是Scheduler调度器的一部分,Event定时器相关的部分也是Scheduler调度器的一部分,而Executor执行模块也存在任务调度的功能,实际上它只需要负责完成调度器交给它的任务就好
  • 没有设计任务调度池,也就是但凡新建计划任务,就会在后台启动一个协程持续监听;一旦任务数量太多,后台停留的协程会越来越多,进程总的消耗就会变得非常夸张,非常可怕
  • 任务调度时不存在优先级的概念,假如相同时间内有多个任务同时执行,哪个任务被优先调度完全取决于GMP的系统调度

定时任务库选择

目前比较主流两种go常用定时库

  • robfig/cron:说到定时任务,会想到 crontab,其常见于Unix和类Unix的操作系统之中。robfig/cron 库使用了类 crontab 的方式来执行定时任务。
  • jasonlvhit/gocron:类 crontab 的设置方式可能并不友好,jasonlvhit/gocron 提供了更为人性化的执行方式。

这里我们使用开源库:robfig/cron
安装库:

go get -u github.com/jasonlvhit/gocron
package main
import(
  "fmt"
  cron "github.com/robfig/cron/v3"
)

func main() {
	crontab := cron.New()
	task := func() {
		fmt.Println("hello world")
	}
  // 添加定时任务, * * * * * 是 crontab,表示每分钟执行一次
	crontab.AddFunc("* * * * *", task)
  // 启动定时器
	crontab.Start()
  // 定时任务是另起协程执行的,这里使用 select 简答阻塞.实际开发中需要
  // 根据实际情况进行控制
	select {}
}

执行命令:

go get github.com/robfig/cron/v3@v3.0.0
go run  main.go

执行效果如下:
在这里插入图片描述
当然,更为复杂的定时任务还有待大家去设计,这里只是一个个小小的案例。

总结

总的来说,一个个小小案例,能够帮助我们了解到许多的工具库与框架,并且理解一些小功能的实现思路,尔后,慢慢利用这些小功能积累成一个个高效、强大的服务模块,这也是徐徐渐进的过程,一起加油!

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

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

相关文章

PySpark实战指南:大数据处理与分析的终极指南【上进小菜猪大数据】

上进小菜猪&#xff0c;沈工大软件工程专业&#xff0c;爱好敲代码&#xff0c;持续输出干货。 大数据处理与分析是当今信息时代的核心任务之一。本文将介绍如何使用PySpark&#xff08;Python的Spark API&#xff09;进行大数据处理和分析的实战技术。我们将探讨PySpark的基本…

P2[1-2]STM32简介(stm32简介+ARM介绍+片上外设+命名规则+系统结构+引脚定义+启动配置+最小系统电路+实物图介绍)

1.1 stm32简介 解释:ARM是核心部分,程序的内核,加减乘除的计算,都是在ARM内完成。 智能车方向:循迹小车,读取光电传感器或者摄像头数据,驱动电机前进和转弯。 无人机:用STM32读取陀螺仪加速度计的姿态数据,根据控制算法控制电机的速度,从而保证飞机稳定飞行。 机…

maven的pom文件

maven项目中会有pom文件&#xff0c; 当新建项目时候&#xff0c; 需要添加我们需要的依赖包。所以整理了一份比较常用的依赖包的pom&#xff0c;方便以后新建项目或者添加依赖包时copy且快捷。不需要的依赖可以删掉&#xff0c;避免首次远程拉取失败和缩小项目打包大小。 <…

爆料,华为重回深圳,深圳第二个硅谷来了-龙华九龙山未来可期

房地产最重要的决定因素&#xff1a;科技等高附加值产业&#xff01;过去几年&#xff0c;发生的最大的变化就是——科技巨头对全球经济的影响力越来越大&#xff0c;中美之间的博弈&#xff0c;由贸易战升级为科技战&#xff0c;就是基于此原因。人工智能、电子信息技术产业、…

工程数值分析(散装/自食/非全)

1.蒙特卡洛 基本流程 蒙特卡洛模拟法基于随机抽样原理&#xff0c;通过生成大量的随机样本&#xff0c;从而对目标变量进行估计和分析。具体来说&#xff0c;蒙特卡洛模拟法的基本流程如下&#xff1a; 1.确定问题&#xff1a;首先需要明确要解决的问题是什么&#xff0c;以及需…

使用腾讯手游助手作为开发测试模拟器的方案---以及部分问题的解决方案

此文主要介绍使用第三方模拟器(这里使用腾讯手游助手)作为开发工具&#xff0c;此模拟器分为两个引擎&#xff0c;一个与其他模拟器一样基于virtualbox的标准引擎&#xff0c;不过优化不太好&#xff0c;一个是他们主推的aow引擎&#xff0c;此引擎。关于aow没有太多的技术资料…

计算机网络(数据链路层,复习自用)

数据链路层 数据链路层功能概述封装成帧与透明传输差错编码&#xff08;检错编码&#xff09;差错编码&#xff08;纠错编码&#xff09;流量控制与可靠传输机制停止-等待协议后退N帧协议&#xff08;GBN&#xff09;选择重传协议&#xff08;Selective Repeat&#xff09; 信道…

ChatGPT-4.5:AI技术的最新进展

✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社区 &#x1f4d9; 专栏地址&#xff1a;AI大模型 OpenAI最新发布的GPT-4&#xff0c;在聊天机器人…

Windows下IDEA创建Java WebApp的一些总结

在踩了无数坑之后&#xff0c;写一下小总结&#xff0c;帮助兄弟们少走弯路 环境准备 Java 这个不用多说&#xff0c;推荐在环境变量Env加入Java Home环境变量&#xff0c;方便后面设置idea 能用Ultimate版本最好&#xff0c;我这种穷B就用Community版本了Mysql 如果是压缩包…

JVM垃圾回收算法及Java引用

目录 Java垃圾回收算法 1.标记清除算法&#xff1a;Mark-Sweep 2.复制算法&#xff1a;copying 3. 标记整理算法&#xff1a;Mark-Compact 4.分代收集算法 5.新生代垃圾回收算法&#xff1a;复制算法 6.老年代&#xff1a;标记整理算法 7.分区收集算法 Java引用 1.Ja…

迪赛智慧数——其他图表(漏斗图):高考生和家长志愿填报困扰问题感知

效果图 高考前的紧张&#xff0c;等分数的忐忑&#xff0c;填志愿的纠结&#xff0c;录取前的煎熬&#xff0c;希望就在不远的前方。 志愿填报心有数&#xff0c;就业前景要关注。收集信息要先行&#xff0c;切莫匆匆抉择定。热门专业不追捧&#xff0c;选择院校不跟风。兴趣爱…

阿里云异构计算GPU、FPGA、EAIS云服务器详细介绍说明

阿里云阿里云异构计算主要包括GPU云服务器、FPGA云服务器和弹性加速计算实例EAIS&#xff0c;随着人工智能技术的发展&#xff0c;越来越多的AI计算都采用异构计算来实现性能加速&#xff0c;阿里云异构计算云服务研发了云端AI加速器&#xff0c;通过统一的框架同时支持了Tenso…

[Daimayuan] 模拟输出受限制的双端队列(C++,模拟)

给你一个输出受限的双端队列&#xff0c;限制输出的双端队列即可以从一端插入元素&#xff0c;弹出元素&#xff0c;但是另一端只可以插入不可以删除元素。即每次你可以执行以下三种操作的其中一种&#xff1a; 在左边压入一个字符在右边压入一个字符弹出最左边的字符 现在给你…

机器学习实战案例用户RFM模型分层(八)

每个产品和公司都需要做用户的精细化运营&#xff0c;它是实现用户价值最大化和企业效益最优化的利器。通过将用户进行分层&#xff1a;如高价值用户、潜在价值用户、新用户、流失用户等&#xff0c;针对不同群体制定个性化的营销策略和客户服务&#xff0c;进而促进业务的增长…

【Java|golang】2465. 不同的平均值数目

给你一个下标从 0 开始长度为 偶数 的整数数组 nums 。 只要 nums 不是 空数组&#xff0c;你就重复执行以下步骤&#xff1a; 找到 nums 中的最小值&#xff0c;并删除它。 找到 nums 中的最大值&#xff0c;并删除它。 计算删除两数的平均值。 两数 a 和 b 的 平均值 为 (a…

(转载)基于蚁群算法的二维路径规划(matlab实现)

1 理论基础 1.1 路径规划算法 路径规划算法是指在有障碍物的工作环境中寻找一条从起点到终点的、无碰撞地绕过所有障碍物的运动路径。路径规划算法较多&#xff0c;大体上可分为全局路径规划算法和局部路径规划算法两类。其中&#xff0c;全局路径规划方法包括位形空间法、广…

Android进阶之路 - 字体自适应

开发中有很多场景需要进行自适应适配&#xff0c;但是关于这种字体自适应&#xff0c;我也是为数不多的几次使用&#xff0c;同时也简单分析了下源码&#xff0c;希望我们都有收获 很多时候控件的宽度是有限的&#xff0c;而要实现比较好看的UI效果&#xff0c;常见的处理方式应…

深度学习的低秩优化:在紧凑架构和快速训练之间取得平衡(上)

论文出处&#xff1a;[2303.13635] Low Rank Optimization for Efficient Deep Learning: Making A Balance between Compact Architecture and Fast Training (arxiv.org) 由于篇幅有限&#xff0c;本篇博客仅引出问题的背景、各种张量分解方法及其分解FC/Conv层的方法&#x…

js算法基础01 --- 数组对象去重

菜狗子的自我救赎01 01- 数组对象去重reduce原生js 利用newObj 和 newArr利用空数组 和 标识flag多条件去重 假设 不知拿id 做对比 还有id2 id 3利用双指针 splice 01- 数组对象去重 把下面数组对象去重 let arr [{ id: 1, name: 周瑜 },{ id: 3, name: 王昭君 },{ id: 2, na…

手动管理采购订单周期的挑战以及如何应对

在过去的几十年里&#xff0c;采购实践有了显著的进步。精明的采购领导正在寻求额外的周期时间的提升。这一点至关重要&#xff0c;因为减少周期时间可以大大提升周转时间&#xff0c;降低你的采购职能的整体成本。它也使采购团队能够将较多的时间用于战略活动。 但是&#xf…