Rust小技巧 - 让函数既可接受String或str,也可以返回String或str

文章目录

    • 1 场景说明
    • 2 解决方案
      • 2.1 允许不同的输入参数
      • 2.2 允许不同的输出参数
      • 2.3 让调用方来做处理
    • 参考资料

1 场景说明

假设我们有一个函数foo,它既要允许&str也要允许String作为输入参数。或是既要允许&str也要允许String作为输出。&strString之间的转换,我们不希望让调用方来操心。这在开发过程中,是经常遇到的需求。

涉及到的知识点:Into,Cow。

2 解决方案

2.1 允许不同的输入参数

我们先来让函数接受不同的输入参数,不同的输入参数可以通过给输入参数绑定Into这个trait来实现。输入参数有这个trait,就可以通过.into()方法来将输入参数转化为需要的类型。

str已经实现了Into这个trait,我们可以直接使用。如果是自己定义的类型,则需要自己实现Into。一般自己实现Into会优先实现From这个trait,有了这个trait,Into就自动实现了,这个是完全免费的。

struct MyStr{s: String
}impl From<MyStr> for String{fn from(s: MyStr)-> Self{s.s}
}fn foo<T: Into<String>>(s: T) -> String{s.into()// 可以在这里做些操作
}fn main() {let s = "abds";let foo_s = foo(s);assert_eq!(String::from("abds"), foo_s);let s = MyStr{s: String::from("jojsd")};let foo_s = foo(s);assert_eq!(String::from("jojsd"), foo_s);
}

2.2 允许不同的输出参数

如果我们希望函数返回不同的参数,可以用Cow,这是一个枚举类型,本质是一个智能指针。

pub enum Cow<'a, B> 
whereB: 'a + ToOwned + ?Sized, {Borrowed(&'a B),Owned(<B as ToOwned>::Owned),
}

ToOwned表示这个泛型B可以从借用变成拥有所有权,比如&str是借用,没有所有权的,通过to_owned()方法,可以变成String,就有所有权了。?Sized表示这个类型的size是不确定的,比如String的长度是可变的。

use std::borrow::Cow;fn foo<'a>(s: &'a str) -> Cow<'a, str>{if s.len() > 5{let s = String::from(&s[0..4]);return Cow::Owned(s);} else {return Cow::Borrowed(s);}}fn main() {let s = "adsfadsf";let mut foo_s = foo(s);assert_eq!("adsf", foo_s.to_mut());assert_eq!("adsf".to_string(), foo_s.into_owned());let s = "adf";let mut foo_s = foo(s);assert_eq!("adf", foo_s.to_mut());assert_eq!("adf".to_string(), foo_s.into_owned());
}

如果既希望输入不同参数,也希望同时返回不同参数,目前还没有找到特别好的办法。

2.3 让调用方来做处理

如果是不希望输入或者输出是可以转换的,我们最好用&str作为输入和输出,因为&String&str的切片都是&str

fn first_word(s: &str) -> &str {let bytes = s.as_bytes();for (i, &item) in bytes.iter().enumerate() {if item == b' ' {return &s[0..i];}}&s[..]
}fn main() {let my_string = String::from("hello world");let word = first_word(&my_string[..]);assert_eq!("hello", word);let word = first_word(&my_string);assert_eq!("hello", word);let my_string_literal = "hello world";let word = first_word(&my_string_literal[..]);assert_eq!("hello", word);let word = first_word(&my_string_literal);assert_eq!("hello", word);
}

参考资料

[1] https://doc.rust-lang.org/std/convert/trait.Into.html
[2] https://hermanradtke.com/2015/05/06/creating-a-rust-function-that-accepts-string-or-str.html/
[3] https://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html/
[4] https://wiki.jikexueyuan.com/project/rust-primer/intoborrow/cow.html
[5] https://doc.rust-lang.org/book/ch04-03-slices.html

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

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

相关文章

JSP九大内置对象(转载)

JSP中一共预先定义了9个这样的对象&#xff0c;分别为&#xff1a;request、response、session、application、out、pagecontext、config、page、exception 1、request对象 request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息&#xf…

recv发送失败 缓冲区太小_从 GFS 失败的架构设计来看一致性的重要性

作者简介 陈东明&#xff0c;饿了么北京技术中心架构组负责人&#xff0c;负责饿了么的产品线架构设计以及饿了么基础架 构研发工作。曾任百度架构师&#xff0c;负责百度即时通讯产品的架构设计。具有丰富的大规模系统构 建和基础架构的研发经验&#xff0c;善于复杂业务需求下…

Rust小技巧 - 把异步函数放进vector当中

文章目录1 场景说明2 解决方案2.1 无借用参数2.2 有借用参数参考资料1 场景说明 有些时候&#xff0c;我们希望将将异步函数放到vector当中&#xff0c;或者说是注册进vector当中&#xff0c;然后在某个地方遍历这个vector来实现对已经注册了的异步函数的调用。 Cargo.toml中…

好用的记事本_分类记事本软件哪个好用?大家推荐一个苹果手机用的分类记事本便签呗...

随着“互联网”的发展&#xff0c;现在都开始在软件上记事备忘了。那么&#xff0c;都有哪些好用的记事本软件可以选择使用呢&#xff1f;大家在选择记事本软件的时候&#xff0c;都有哪些标准呢&#xff1f;不知道大家的标准是什么&#xff0c;小编有一个不能妥协的标准&#…

tch-rs指南 - Tensor的基本操作

文章目录1 概述2 Tensor的基本操作2.1 Tensor的初始化&#xff08;1&#xff09;通过数组创建&#xff08;2&#xff09;通过默认方法创建&#xff08;3&#xff09;通过其他的tensor创建&#xff08;4&#xff09;通过opencv::core::Mat创建2.2 Tensor的属性2.3 Tensor的运算&…

命令行运行jmeter脚本

1、通过gui界面的jmeter创建一份脚本&#xff1b;2、打开cmd,切换到jmeter程序的Bin目录&#xff1b;3、执行jmeter.bat -n -t bookair_0613.jmx -l log_3.jtl&#xff1b;4、使用gui界面添加一个监听器&#xff0c;打开log_3.jtl文件&#xff0c;来分析测试结果。转载于:https…

bootstrap table 分页_Java入门007~springboot+freemarker+bootstrap快速实现分页功能

本节是建立在上节的基础上&#xff0c;上一节给大家讲了管理后台表格如何展示数据&#xff0c;但是当我们的数据比较多的时候我们就需要做分页处理了。这一节给大家讲解如何实现表格数据的分页显示。准备工作1&#xff0c;项目要引入freemarker和bootstrap&#xff0c;如果不知…

Rust小技巧 - 通过FFI编程运行tensorrt模型

文章目录1 概述2 使用说明2.1 配置说明2.2 修改c头文件2.3 编写build.rs2.4 测试参考资料1 概述 shouxieai/tensorRT_Pro是一个文档完善&#xff0c;效果也很不错的tensorrt库&#xff0c;里面有对yolov5&#xff0c;yolox&#xff0c;unet&#xff0c;bert&#xff0c;retina…

1+X web中级 Laravel学习笔记——查询构造器简介及新增、更新、删除、查询数据

一、新增数据 插入多条数据&#xff1a; 二、更新数据 更新某条数据&#xff1a; 自增某字段的值&#xff1a; 自减某字段的值&#xff1a; 自增的同时改变其他字段的值&#xff1a; 三、删除数据 四、查询 查面构造器查面数据 有以下几种方法 get&#xff08;&…

【HTML5】Canvas画布

什么是 Canvas&#xff1f; HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。 画布是一个矩形区域&#xff0c;您可以控制其每一像素。 canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。 * 添加 canvas 元素。规定元素的 id、宽度和高度&#xff1a; &l…

SynthText流程解读 - 不看代码不知道的那些事

文章目录1 概述2 流程解读2.1 生成文字mask2.2 plane2xyz的bug2.3 文字上色2.4 图像融合参考资料1 概述 SynthText是OCR领域生成数据集非常经典&#xff0c;且至今看来无人超越的方法。整体可以分为三个大的步骤&#xff0c;分别是生成文字的mask&#xff0c;这里用到了图像的…

python if name main 的作用_Python中if __name__ == '__main__':的作用和原理

if __name__ __main__:的作用 一个python文件通常有两种使用方法&#xff0c;第一是作为脚本直接执行&#xff0c;第二是 import 到其他的 python 脚本中被调用&#xff08;模块重用&#xff09;执行。因此 if __name__ main: 的作用就是控制这两种情况执行代码的过程&#x…

1+X web中级 Laravel学习笔记——Eloquent ORM查询、更新、删除、新增

Eloquent ORM简介 larave1所自带的Eloquent oRM是一个非常优美简洁的ActiveRecord实现&#xff0c;用来实现数据库的操作他的每个数据的表都有对应的模型&#xff08;model&#xff09;用于数据表的交互模型的建立 一、Eloquent ORM的查询 二、Eloquent ORM新增 通过模型新增…

使用复合设计模式扩展持久化的CURD,Select能力

大家可能会经常遇到接口需要经常增加新的方法和实现&#xff0c;可是我们原则上是不建议平凡的增加修改删除接口方法&#xff0c;熟不知这样使用接口是不是正确的接口用法&#xff0c;比如我见到很多的项目分层都是IDAL&#xff0c;DAL&#xff0c;IBLL&#xff0c;BLL&#xf…

python脚本加密_教你如何基于python实现脚本加密

这篇文章主要介绍了如何基于python实现 脚本加密,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 from pathlib import Path import python_minifier import compileall import sys def get_save_path(from_dir,…

1+X web中级 Laravel学习笔记——blade模版

一、blade模版简介 Blade是larave1提供的一个既简单又强大的模版引擎和其他的流行的php模版引擎不一样&#xff0c;blade并不限制你在视图&#xff08;view&#xff09;中使用原生php代码 二、 模版继承 section yield extents parent 三、基本语法以及include的使用 1…

matplotlib 散点图_matplotlib画图 绘制散点图案例

假设通过爬虫你获取到了北京2016年3,10月份 每天白天的最高气温(分别位于列表a,b), 那么此时如何寻找出气温和随时间(天)变化的某种规律? a [11,17,16,11,12,11,12,6,6,7,8,9,12,15,14,17,18,21,16,17,20,14,15,15,15,19,21,22,22,22,23] b [26,26,28,19,21,17,16,19,18,20,…