Rust5.2 Generic Types, Traits, and Lifetimes
Rust学习笔记
Rust编程语言入门教程课程笔记
参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community)
Lecture 10: Generic Types, Traits, and Lifetimes
lib.rs
use std::fmt::Display;//Traits: Defining Shared Behavior
pub trait Summary {fn summarize_author(&self) -> String;// fn summarize(&self) -> String;fn summarize(&self) -> String {//String::from("(Read more from...)")format!("(Read more from {}...)", self.summarize_author())}}pub struct NewsArticle {pub headline: String,pub location: String,pub author: String,pub content: String,
}impl Summary for NewsArticle {//implementing a trait on a type// fn summarize(&self) -> String {//implementing a trait method// format!("{}, by {} ({})", self.headline, self.author, self.location)// }fn summarize_author(&self) -> String {//implementing a trait methodformat!("{}", self.author)}}pub struct Tweet {pub username: String,pub content: String,pub reply: bool,pub retweet: bool,
}impl Summary for Tweet {//implementing a trait on a typefn summarize(&self) -> String {//implementing a trait methodformat!("{}: {}", self.username, self.content)}fn summarize_author(&self) -> String {//implementing a trait methodformat!("{}", self.username)}}pub fn notify(item: &impl Summary) {println!("Breaking news! {}", item.summarize());
}pub fn notify_trait_bound<T: Summary>(item: &T) {//trait bound syntaxprintln!("Breaking news! {}", item.summarize());
}pub fn notify_trait_bounds<T: Summary>(item1: &T, item2: &T) {//trait bound syntaxprintln!("Breaking news! {}", item1.summarize());println!("Breaking news! {}", item2.summarize());
}pub fn notify_multiple_trait_bounds<T: Summary + Display>(item1: &T, item2: &T) {//trait bound syntaxprintln!("Breaking news! {}", item1.summarize());println!("Breaking news! {}", item2.summarize());
}pub fn notify_where_clause<T, U>(item1: &T, item2: &U) where T: Summary + Display,U: Summary + Display
{println!("Breaking news! {}", item1.summarize());println!("Breaking news! {}", item2.summarize());
}//Returning Types that Implement Traits
fn _returns_summarizable() -> impl Summary {//returning a type that implements the Summary trait//cannot return different typesTweet {username: String::from("horse_ebooks"),content: String::from("of course, as you probably already know, people"),reply: false,retweet: false,}
}struct _Pair<T> {x: T,y: T,
}impl <T> _Pair<T> {fn _new(x: T, y: T) -> Self {Self {x,y,}}}impl <T: Display + PartialOrd> _Pair<T> {//trait bound syntaxfn _cmp_display(&self) {if self.x >= self.y {println!("The largest member is x = {}", self.x);} else {println!("The largest member is y = {}", self.y);}}}//blanket implementations
// impl<T: Display> ToString for T {
// // --snip--
// }
main.rs
use generic_types_traits_and_lifetimes::Summary;
use generic_types_traits_and_lifetimes::Tweet;
use std::fmt::Display;//Generic Data Types
fn largest_generic<T:std::cmp::PartialOrd + Clone>(list: &[T]) -> &T {let mut largest = &list[0];for item in list {if item > largest { //error: the trait `std::cmp::PartialOrd` is not implemented for `T`largest = item;}}largest
}struct Point<T> {x: T,y: T,
}impl Point<i32> {fn selfx(&self) -> &i32 {&self.x}}impl Point<f32> {fn distance_from_origin(&self) -> f32 {(self.x.powi(2) + self.y.powi(2)).sqrt()}
}impl Point<&str>{fn concatenate(&self) -> String {format!("{}{}", self.x, self.y)}
}#[derive(Debug)]
struct Point2<T, U> {x: T,y: U,
}impl<T, U> Point2<T, U> {fn mixup<V, W>(self, other: Point2<V, W>) -> Point2<T, W> {Point2 {x: self.x,y: other.y,}}
}//Lifetime Annotations in Struct Definitions
struct _ImportantExcerpt<'a> {_part: &'a str,
}fn main() {//remove duplication by extracting the match expression into a functionlet number_list = vec![34, 50, 25, 100, 65];// let mut largest = &number_list[0];// for number in &number_list {// if number > largest {// largest = number;// }// }//largest function with generic typelet result1 = largest(&number_list);println!("The largest number is {}", result1);//duplicationlet number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8];// let mut largest = &number_list[0];// for number in &number_list {// if number > largest {// largest = number;// }// }//largest function with generic typelet result2 = largest(&number_list);println!("The largest number is {}", result2);let str_list = vec!["Hello", "Rust", "World"];let result3 = largest_generic(&str_list);println!("The largest string is {}", result3);//Generic Data Types in Struct Definitionslet integer = Point { x: 5, y: 10 };println!("x,y = {},{}", integer.x, integer.y);let float = Point { x: 1.0, y: 4.0 };println!("x,y = {},{}", float.x, float.y);//Generic Data Types in Enum Definitionslet integer = Option::Some(5);let float = Option::Some(5.0);let none: Option<i32> = None;println!("integer = {:?}, float = {:?}, none = {:?}", integer, float, none);println!("integer = {:?}, float = {:?}, none = {:?}", integer, float, none);//Generic Data Types in Method Definitionslet p1 = Point { x: 5, y: 10 };let p2 = Point { x: "Hello", y: " Rust" };let p3 = Point { x: 5.0, y: 10.0 };println!("p1:{}",p1.selfx());println!("p2:{}",p2.concatenate());println!("p3:{}",p3.distance_from_origin());//Generic Data Types in Struct Definitionslet p4 = Point2 { x: 5, y: 10.4 };let p5: Point2<&str, i32> = Point2 {x:"Hello", y:2};println!("p4:{:?}",p4.mixup(p5));//Traits: Defining Shared Behaviorlet tweet = Tweet {username: String::from("horse_ebooks"),content: String::from("of course, as you probably already know, people"),reply: false,retweet: false,};println!("1 new tweet: {}", tweet.summarize());//Lifetimes: Ensuring One Borrow Lasts as Long as the Other//avoiding dangling references// let r;// //let b = r;//error: use of possibly uninitialized `r`// {// let x = 5;// r = &x;// }// //borrow checker// //println!("r:{}",r);//error: `x` does not live long enoughlet x = 5;let r = &x;println!("r:{}",r);let string1 = String::from("abcd"); let string2 = "xyz";let result = longest(string1.as_str(), string2);println!("The longest string is {}", result);//Lifetime Annotations in Struct Definitionslet novel = String::from("Call me Ishmael. Some years ago...");let first_sentence = novel.split('.').next().expect("Could not find a '.'");let _i = _ImportantExcerpt { _part: first_sentence };//Lifetime Elision}fn largest(list: &[i32]) -> &i32 {//we need to return a reference to the valuelet mut largest = &list[0];for number in list {if number > largest {largest = number;}}largest
}//Lifetime Annotation Syntax
//'a is a generic lifetime parameter
//&'a str: a string slice that lives for the lifetime 'a
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {//we need to return a reference to the value//'a is the part of the scope of x that overlaps with the scope of yif x.len() > y.len() {x} else {y}
}fn _longest<'a>(x: &'a str, _y: &str) -> &'a str {//we need to return a reference to the value//'a is the part of the scope of x that overlaps with the scope of yx
}// fn error_longest<'a>(x: &str, _y: &str) -> &'a str {//we need to return a reference to the value
// let result = String::from("really long string");
// result.as_str()
// }fn _corroct_longest<'a>(_x: &'a str, _y: &str) -> String {//we need to return a reference to the valuelet result = String::from("really long string");result
}//Lifetime Elision
//The compiler uses three rules to figure out what lifetimes references have when there aren’t explicit annotations.
//The first rule applies to input lifetimes, and the second and third rules apply to output lifetimes.
//If the compiler gets to the end of the three rules and there are still references for which it can’t figure out lifetimes, the compiler will stop with an error.//1. Each parameter that is a reference gets its own lifetime parameter.
//2. If there is exactly one input lifetime parameter, that lifetime is assigned to all output lifetime parameters: fn foo<'a>(x: &'a i32) -> &'a i32.
//3. If there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all output lifetime parameters.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 _longest_with_an_announcement<'a, T>(x: &'a str,y: &'a str,ann: T,
) -> &'a str where T: Display
{println!("Announcement! {}", ann);if x.len() > y.len() {x} else {y}
}
相关文章:
Rust5.2 Generic Types, Traits, and Lifetimes
Rust学习笔记 Rust编程语言入门教程课程笔记 参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community) Lecture 10: Generic Types, Traits, and Lifetimes lib.rs use std::fmt::Display;//Traits: …...
c 实用化的摄像头生成avi视频程序(加入精确的时间控制)
I时间控制是指:生成了n张图片帧用了多少时间m。帧率等于n/m。对应于头文件,m等于scale, n等于rate.为了精确,采用微秒计时。 I此程序生成的视频远好于ffmpeg,可能是此程序没有压缩数据原因吧。 现在的帧率不高,是因…...
Web后端开发_01
Web后端开发 请求响应 SpringBoot提供了一个非常核心的Servlet 》DispatcherServlet,DispatcherServlet实现了servlet中规范的接口 请求响应: 请求(HttpServletRequest):获取请求数据响应(HttpServletRe…...
二十、泛型(6)
本章概要 问题 任何基本类型都不能作为类型参数实现参数化接口转型和警告重载基类劫持接口 自限定的类型 古怪的循环泛型自限定参数协变 问题 本节将阐述在使用 Java 泛型时会出现的各类问题。 任何基本类型都不能作为类型参数 正如本章早先提到的,Java 泛型的…...
Java18新增特性
前言 前面的文章,我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16、Java17 的特性进行了介绍,对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 Java14新增特性 Java15新增特性 Java…...
springboot容器
1.主要指的是servlet容器 servlet组件由sevlet Filter Listener等 2.自动配置原理 通过ServletWebServerFactoryAutoConfiguration 配置这些内容 (自动配置类开始分析功能) conditionalOnclass开启条件 ServletRequest类 import导入嵌入式的tomcat Jetty等 这些是配置类&…...
Windows 10 下使用Visual Studio 2017 编译CEF SDK
1.下载CEF SDK 由于需要跑在32位的机器,所以选择下载32位的SDKCEF Automated Builds 选择 Current Stable Build (Preferred) ,这是当前稳定版本,CEF版本118 下载成功解压 2.下载编译工具 CMake 下载地址:CMake 配置CMake指向…...
数字货币swap交易所逻辑系统开发分析方案
随着数字货币市场的快速发展, Swap交易所已成为一种重要的交易方式。本文将对数字货币Swap交易所逻辑系统开发进行分析,并探讨其优势、开发难点和解决方案。 一、数字货币Swap交易所逻辑系统开发的优势 数字货币Swap交易所是一种点对点的交易方式&#x…...
spring boot中使用Bean Validation做优雅的参数校验
一、Bean Validation简介 Bean Validation是Java定义的一套基于注解的数据校验规范,目前已经从JSR 303的1.0版本升级到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于2017.08),目前最新稳定版2.0.2(201…...
搜索引擎项目
认识搜索引擎 1、有一个主页、有搜索框。在搜索框中输入的内容 称为“查询词” 2、还有搜索结果页,包含了若干条搜索结果 3、针对每一个搜索结果,都会包含查询词或者查询词的一部分或者和查询词具有一定的相关性 4、每个搜索结果包含好几个部分&…...
7.外部存储器,Cache,虚拟存储器
目录 一. 外部存储器 (1)磁盘存储器 1.磁盘的组成 2.磁盘的性能指标 3.磁盘地址 4.硬盘的工作过程 5.磁盘阵列 (2)固态硬盘(SSD) 二. Cache基本概念与原理 三. Cache和主存的映射方式 ÿ…...
UITableView的style是UITableViewStyleGrouped
一般情况下,UITableViewStylePlain和UITableViewStyleGrouped是UITableView常用到的style, 之前都是用到的时候,遇到问题直接用度娘,差不多就够用了,今天在修复UI提出的间隙问题,来回改,总觉得…...
Java17新增特性
前言 前面的文章,我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16 的特性进行了介绍,对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 Java14新增特性 Java15新增特性 Java16新增特…...
VR全景技术在城市园区发展中有哪些应用与帮助
引言: 在数字化时代的浪潮中,虚拟现实(VR)全景技术逐渐融入各个领域,也为城市园区展示带来了全新的可能性。 一.VR全景技术简介 虚拟现实全景技术是一种通过全景图像和视频模拟真实环境的技术。通过相关设…...
在 SQL 中,当复合主键成为外键时应该如何被其它表引用
文章目录 当研究一个问题慢慢深入时,一个看起来简单的问题也暗藏玄机。在 SQL 中,主键成为外键这是一个很平常的问题,乍一看没啥值得注意的。但如果这个主键是一种复合主键,而另一个表又引用这个键作为它的复合主键,问…...
Ps:通过显示大小了解图像的打印尺寸
在 Photoshop 中,如果想了解文档窗口中的图像打印出来之后的实质大小,只要知道两个数值即可。 第一个数值是图像分辨率(也称“文档分辨率”)的大小,可在Ps菜单:图像/图像大小 Image Size对话框中查询或设置…...
Linux - 驱动开发 - watchdog - SMP机制下多核确活
说明 理论上:不管IC是单核还是多核,只要watchdog有被循环feed,就不会触发超时重启,因此watchdog在SMP机制下的多核环境显得比较宽松,只要任意核存活(喂狗)就不会重启设备。 实际情况 有客户反…...
概念解析 | LoRA:低秩矩阵分解在神经网络微调中的魔力
注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:基于低秩矩阵分解的神经网络微调方法LoRA LoRA:低秩矩阵分解在神经网络微调中的魔力 Low-Rank Adaptation of Large Language Models LoRA由如下论文提出,详细信息请参见论文原…...
量子计算和量子通信技术:引领潜力无限的未来
近年来,随着量子计算和量子通信技术的迅速发展,它们在各个领域的广泛应用前景引起了人们的极大兴趣。本文将深入探讨量子计算和量子通信技术的普遍应用,以及它们预示的未来,同时提出业内人士需要注意的事项。 介绍:量子…...
nodejs+vue+python+PHP+微信小程序-安卓- 电影在线订票系统的设计与实现-计算机毕业设计推荐
目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性:…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
