Rust宏示例和实践【译】

原文链接为 https://earthly.dev/blog/rust-macros/ ,文章大部分使用机器翻译,小部分进行了文字调整。 本文深入探讨 Rust 宏的强大功能和多功能性。 Earthly 保证构建过程与您创建的宏一样强大。了解更多关于地球的信息。 在 Rust 中,宏是使用通常称为元编程的技术生成其他 Rust 代码的代码片段。宏在编译期间被扩展,并且宏的输出被插入到程序的源代码中。 最著名的宏示例是 println! 。尽管它看起来像函数并且使用起来也像函数,但它实际上在编译过程中进行了扩展,并且 println! 调用被替换为更复杂的实现代码。 在本文中,您将看到一些宏的实际示例,并了解一些有关如何最好地使用它们的提示和技巧。 Rust 宏基础知识 本教程假设您熟悉 Rust 编程的基础知识。 在 Rust 中,有两种类型的宏:声明性宏和过程性宏。逐一查看: 声明性宏 声明性宏是最简单的宏类型,由 macro-rules! 宏定义。它们的外观和行为与 match 表达式类似。 match 表达式将表达式作为输入,并将其与一组预定义模式进行匹配并运行相应的代码。类似地,声明性宏将一段 Rust 源代码作为输入,将源代码与一组预定义的结构进行匹配,并且在成功匹配时,将代码替换为与匹配模式关联的代码。 以下示例显示了正在运行的声明性宏: declarative_macro.rs//declarative_macro.rs macro_rules! greetings { ($x: expr) => { println!("Hello, {}", $x); }; } fn main() { greetings!("Earthly"); // Prints "Hello, Earthly" } 这里,宏被命名为 greetings 并用 macro_rules! 定义。在宏主体中,只有一种模式: ($x: expr) => { ....

January 28, 2024 · 7 min · czyt

在 Rust 中使用 Serde【译】

本文原文链接为 https://www.shuttle.rs/blog/2024/01/23/using-serde-rust 。大部分使用机器翻译,个人对机器翻译内容进行了部分润色,对于部分内容进行了增补。 在本文中,我们将讨论 Serde、如何在 Rust 应用程序中使用它以及一些更高级的提示和技巧。 什么是serde? serde Rust create用于高效地序列化和反序列化多种格式的数据。它通过提供两个可以使用的trait来实现这一点,恰当地命名为 Deserialize 和 Serialize 。作为生态系统中最著名的 crate 之一,它目前支持 20 多种类型的序列化(反序列化)。 首先,您需要将 crate 安装到您的 Rust 应用程序中: cargo add serde 使用serde 反序列化和序列化数据 序列化和反序列化数据的简单方法是添加 serde derive 功能。这会添加一个宏,您可以使用它来自动实现 Deserialize 和 Serialize - 您可以使用 --features 标志( -F 来实现)短的): cargo add serde -F derive 然后我们可以将宏添加到我们想要实现 Deserialize 或 Serialize 的任何struct体或enum(枚举)中: use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize)] struct MyStruct { message: String, // ... the rest of your fields } 这允许我们使用任何支持 serde 的包在所述格式之间进行转换。作为示例,让我们使用 serde-json 与 JSON 格式相互转换:...

January 25, 2024 · 6 min · czyt

转换数字到Excel列字母实现

根据微软官方文档,excel最大支持1,048,576 行, 16,384 列。下面的代码并未处理这一限制。 Rust 实现代码: fn convert_to_title(mut n: i32) -> String { let mut result = String::new(); while n != 0 { n -= 1; let letter = (n % 26) as u8 + b'A'; result.insert(0, letter as char); n /= 26; } result } #[test] fn test_convert_to_title() { let aa = convert_to_title(27); assert_eq!(aa, "AC"); } Go 实现代码: func convertToTitle(n int) string { result := "" for n > 0 { n-- letter := n%26 result = string('A'+letter) + result n /= 26 } return result } C# 实现代码:...

January 25, 2024 · 1 min · czyt

关于七牛qetag算法的一些记录

背景 今天做七牛相关接口开发的时候发现七牛的文件查询列表返回,有个hash字段,但是不知道是怎么进行计算的。后来查询到七牛的官方仓库 qetag.官方对这个算法的描述是这样的: qetag 是一个计算文件在七牛云存储上的 hash 值(也是文件下载时的 etag 值)的实用程序。 七牛的 hash/etag 算法是公开的。算法大体如下: 如果你能够确认文件 <= 4M,那么 hash = UrlsafeBase64([0x16, sha1(FileContent)])。也就是,文件的内容的sha1值(20个字节),前面加一个byte(值为0x16),构成 21 字节的二进制数据,然后对这 21 字节的数据做 urlsafe 的 base64 编码。 如果文件 > 4M,则 hash = UrlsafeBase64([0x96, sha1([sha1(Block1), sha1(Block2), …])]),其中 Block 是把文件内容切分为 4M 为单位的一个个块,也就是 BlockI = FileContent[I*4M:(I+1)*4M]。 为何需要公开 hash/etag 算法?这个和 “消重” 问题有关,详细见: https://developer.qiniu.com/kodo/kb/1365/how-to-avoid-the-users-to-upload-files-with-the-same-key http://segmentfault.com/q/1010000000315810 为何在 sha1 值前面加一个byte的标记位(0x16或0x96)? 0x16 = 22,而 2^22 = 4M。所以前面的 0x16 其实是文件按 4M 分块的意思。 0x96 = 0x80 | 0x16。其中的 0x80 表示这个文件是大文件(有多个分块),hash 值也经过了2重的 sha1 计算。 语言封装 C# 实现 基于官方仓库的csharp代码做了部分修改...

January 22, 2024 · 3 min · czyt

Golang 高级时间工具函数

本文为 https://medium.com/canopas/golang-date-time-utilities-part-2-b1192eb04842 文章的翻译。正文部分进行了部分调整。 背景介绍 在编程世界中,处理日期和时间是一项常见的任务,通常需要精确性和灵活性。 虽然 Go 编程语言的标准库提供了 time 软件包来处理与时间相关的操作,但在某些情况下,开发人员需要额外的实用程序来简化与时间相关的任务。 在本篇博文中,我们将探讨一组实用工具函数,它们是 time 程序包的封装,可为操作提供便利。如果您不了解 time程序包,请考虑在深入学习高级实用程序之前参考一下相关文档。 有关基本功能,请参阅您始终需要的时间实用功能。 🎯 那么,让我们深入探讨一下如何实现。 实现 1.获取月初 一个月的开始是许多日期相关计算的基本参考点。让我们创建一个函数,将日期作为输入,并根据系统时区返回相应月份的第一天: func StartOfMonth(date time.Time) time.Time { return time.Date(date.Year(), date.Month(), 1, 0, 0, 0, 0, date.Location()) } // function called StartOfMonth(time.Now()) // output 2024-01-01 00:00:00 +0530 IST 此函数将月日设置为 1,其他部分保持不变。 2.获取月末数据 相反,获取月末也同样重要。下面的函数返回给定月份最后一天的最后一秒: func EndOfMonth(date time.Time) time.Time { firstDayOfNextMonth := StartOfMonth(date).AddDate(0, 1, 0) return firstDayOfNextMonth.Add(-time.Second) } // function called EndOfMonth(time.Now()) // output 2024-01-31 23:59:59 +0530 IST 该函数利用之前定义的 StartOfMonth 函数查找下个月的第一天,然后减去一秒,得到当前月份的月底。...

January 18, 2024 · 4 min · czyt

如何获取一个Github或者gitlab用户的公钥

背景 今天无意在t上看到,然后找到这个帖子 https://stackoverflow.com/questions/16158158/what-is-the-public-url-for-the-github-public-keys How TO 获取 GitHub 可以通过下面链接 https://github.com/USER.keys https://github.com/USER.gpg 当然也可以通过github的api方式来获取 curl -i https://api.github.com/users/<username>/keys GitLab可以使用下面链接 https://gitlab.com/USER.keys https://gitlab.com/USER.gpg 使用 以github为例 curl https://github.com/<username>.keys | tee -a ~/.ssh/authorized_keys 添加完毕以后,对方就可以用ssh直接连接到你的电脑了。 这个帖子还举了bitbucket的例子 curl -i https://bitbucket.org/api/1.0/users/<accountname>/ssh-keys 延伸阅读 史上最全 SSH 暗黑技巧详解

January 17, 2024 · 1 min · czyt

Google Service Weaver中文文档[机翻]

本文为 Service Weaver 文档的机器翻译+细节微调。 Service Weaver是什么 ? Service Weaver 是一个用于编写、部署和管理分布式应用程序的编程框架。您可以在计算机上本地运行、测试和调试 Service Weaver 应用程序,然后使用单个命令将该应用程序部署到云。 $ go run . # Run locally. $ weaver ssh deploy weaver.toml # Run on multiple machines. $ weaver gke deploy weaver.toml # Run on Google Cloud. $ weaver kube deploy weaver.toml # Run on Kubernetes. Service Weaver 应用程序由许多组件组成。组件被表示为常规的 Go 接口,组件之间通过调用这些接口定义的方法进行交互。这使得编写 Service Weaver 应用程序变得容易。您不必编写任何网络或序列化代码;你只要写 Go 就可以了。 Service Weaver 还提供用于日志日志、指标、跟踪、路由、测试等的库。 您可以像运行单个命令一样轻松地部署 Service Weaver 应用程序。在幕后,Service Weaver 将沿着组件边界Profile您的二进制文件,从而允许不同的组件在不同的计算机上运行。 Service Weaver 将为您复制、自动缩放和共同定位这些分布式组件。它还将代表您管理所有网络详细信息,确保不同的组件可以相互通信,并且客户端可以与您的应用程序通信。...

January 12, 2024 · 37 min · czyt

一些使用go-fyne的笔记

界面交互 中文字体设置 查阅相关资料,有下面几种解决方案,下面来依次说明。 环境变量 可以通过指定 FYNE_FONT 环境变量来使用替代字体 使用字体bundle 安装fyne工具,使用下面的命令: go install fyne.io/fyne/v2/cmd/fyne@latest 准备好要使用的字体,我们这里使用miSans,使用下面命令 fyne bundle MiSans-Normal.ttf > bundle.go 然后创建一个theme package tinytheme import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/theme" "fyneHello/fontRes" "image/color" ) type ChineseTheme struct{} var _ fyne.Theme = (*ChineseTheme)(nil) func (m *ChineseTheme) Font(s fyne.TextStyle) fyne.Resource { return fontRes.ResourceMiSansTTF } func (*ChineseTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color { return theme.DefaultTheme().Color(n, v) } func (*ChineseTheme) Icon(n fyne.ThemeIconName) fyne.Resource { return theme.DefaultTheme().Icon(n) } func (*ChineseTheme) Size(n fyne....

January 11, 2024 · 11 min · czyt

使用go来编写graphql服务

本文为 文章 Go GraphQL Go!!! A beginner’s guide to GraphQL in Go using Ent. 的翻译。大部分使用机翻,部分内容作了相应调整。原文地址为 https://psj.codes/go-graphql-go 您是否想知道计算机和应用程序如何相互通信以获取信息?嗯,他们使用一种称为 API 的东西,它代表应用程序编程接口。 API 充当桥梁,允许不同的软件系统相互通信并交换数据。 在互联网的早期,构建 API 具有挑战性。开发人员必须以一种对每个使用它们的人都有意义的方式进行设计。这就像试图从调酒师那里点一杯饮料,而调酒师的菜单很复杂,有太多的选择。您通常会得到比您需要的更多或不够的信息,例如订购一杯简单的橙汁并收到整个水果篮!这给开发人员带来了挫败感并浪费了时间,他们必须筛选不必要的数据或发出多个请求才能获得他们想要的东西。想象一下,您必须向调酒师要一杯饮料,但您收到的不是简单的订单,而是完整的饮料目录!更糟糕的是,传统 API(称为 REST API)依赖大量端点。这些端点充当访问数据不同部分的特定路径。这就像一个迷宫,里面有无数扇门需要穿过。但随后,改变游戏规则的事情发生了。 Facebook 在 2012 年推出了 GraphQL,这是一种构建 API 的革命性方法,彻底扭转了局面。借助 GraphQL,开发人员终于告别了数据过度获取和数据获取不足的麻烦。快进到 2015 年,Facebook 开源了 GraphQL,并于 2018 年将 GraphQL 捐赠给了 Linux 基金会。 GraphQL 是一种 API 查询语言,或者有人可能会说它是开发 API 的新标准。 在本博客中,我们将探讨 GraphQL 如何应对传统 REST API 面临的挑战。我们还将踏上在 Go 中构建 GraphQL 服务器的实践之旅,为了使我们的开发过程更加令人兴奋和高效,我们将利用 Ent 的强大功能,这是一个专为 Go 设计的令人惊叹的实体库。 GraphQL 救世主 在简介中,我们提到了 RESTful API 的问题。让我们尝试理解它们并研究 GraphQL 如何解决它们。...

December 29, 2023 · 11 min · czyt

golang并发二三事

本文主要是鸟窝《深入理解go并发编程》中的读书速记以及一些并发库的使用例子集合 常用的并发库使用 sourcegraph conc waitgroup 创建一组协程并等待完成: 标准库 func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() // crashes on panic! doSomething() }() } wg.Wait() } conc func main() { var wg conc.WaitGroup for i := 0; i < 10; i++ { wg.Go(doSomething) } wg.Wait() } 下面是一个官网博客的例子: 写一个函数,给定用户的名字,通过网络获取姓氏 func fetchLastName(ctx context.Context, firstName string) (string, error) { req, err := http....

December 18, 2023 · 3 min · czyt