当前位置: 首页 > news >正文

Rust学习(五):泛型、trait

Rust学习(五):泛型、trait

1、泛型:

相信小伙伴们一定还记得,之前我们实现了一个add函数,并指定了参数类型为:i32:

fn add(x:i32, y:i32) ->i32 {x + y
}

这里我们就会遇到一个问题,如果我们想为两个f64类型的变量进行加法运算,那么就必须为这两个f64类型的变量重载这个add函数:

fn add(x:f64, y:f64) ->f64 {x + y
}

完成函数的重载之后,就可以正常对两个f64类型的变量使用add()方法进行加法运算了!但是,如果我们要为所有数值类型的变量都实现这样一个add函数,难道要逐个类型的进行函数重载吗?那整个代码将变得过于冗余和难以管理,在Rust中为了处理这种重复性的问题,引出了泛型的概念。

泛型是对具体类型或者属性的抽象替代,实际使用中只需要表达泛型的属性,而不需要在编写代码时知道实际上是什么类型,举一个具体的例子,比如有一所学校,要求所有学生都要穿着校服进校,这时学校是对学生全体进行的要求,无论是男生,还是女生,都要穿着校服进校,此时男生就像i32类型,女生就是f64类型,而学生就是对男生和女生抽象出来的泛型。

//通过泛型实现add函数:
fn add<T>(x:T, y:T) ->T {x + y
}

上面这个函数就可以完美实现各种数值类型的数据的加法运算,在函数声明中,add后面的尖括号里存放的就是泛型参数T(实际上这里和形参一样,T,E,G…都可以)了,旨在向编译器说明这是一个泛型函数,将泛型的概念拓展开来,也可以使用到其他类型的程序组件:

// 泛型枚举:
enum Result<T, E> {  //可以看到泛型参数可以不止一个Ok(T),Err(E),
}// 泛型结构体:
struct Point<T> {x: T,y: T,
}

事实上,即便引入了泛型的概念,依然不能完全解决add函数的问题,可以试想一下:如果传入的参数是两个字符类型呢?那么编译器必然会直接报错(一点面子都不给,doge)。下面我们介绍的trait就可以实现对泛型的一种定义和限制。

2、trait:

trait可以被译为特性(似乎没有一个官方的中午翻译,特性一词可能较为符合),trait由常量,方法和类型三部分组成,它定义了一种抽象的接口,这种抽象既可以被类型实现,也可以直接继承默认实现。rust通过trait、impl可以实现类似于C++、python等语言中class中封装、继承和多态的功能,因此具备了面向对象编程的可能,下面定义了老师和学生两种类型(结构体),并实现了打招呼的trait:

trait Greete {//定义打招呼的traitfn say_hello(&self) {println!("Nice to see you!");}
}//定义Teacher和Student类型:
struct Teacher {edu: i32,teach: i32,
}struct Student {edu: i32,
}impl Greete for Student {} //学生类型直接继承Greete的say_hello打招呼方法
impl Greete for Teacher {// 教师类型要重载say_hello方法:fn say_hello(&self) {println!("Nice to see you, too!");}
}fn main() {let s = Student {edu:3};let t = Teacher {edu:30, teach:5};s.say_hello();t.say_hello();
}

好了,现在我们对trait已经有了一个基础的(模糊的,这部分确实难)理解,现在让我们来解决在泛型中遇到的问题,如何通过trait来约束泛型:

// 泛型约束:
fn outer_say_hello<T:Greete>(t:$T) {t.say_hello();
}let stu = Student{edu:12};
outer_say_hello(&stu);

在约束函数outer_say_hello函数加上了泛型约束T:Greete,表明只有实现了Greete这个trait的类型T才能调用say_hello函数,这种泛型约束被称为trait bound。当然,trait bound还有一种语法糖使用方法:impl trait,我们用这种方式,来实现对add函数的约束:

fn add(x: &impl Addable, y: &impl Addable) {x + y
}

trait和类型都可能有很多个,为了避免在尖括号过长,影响代码的可读性,rust提供了where方法:

fn some_func<T, U>(x: T, y: U) where T: trait1 + trait2U: trait1
{do_some_work();
}

泛型和trait在rust中相当重要,需要仔细理解和体悟。

http://www.lryc.cn/news/485788.html

相关文章:

  • 智能零售柜商品识别
  • 2024智能机器人与自动控制国际学术会议 (IRAC 2024)
  • 计算机组成原理:总线与微命令
  • 10月回顾 | Apache SeaTunnel社区动态与进展一览
  • 网络基础(4)传输层
  • 计算机的错误计算(一百五十六)
  • 爬虫开发工具与环境搭建——开发工具介绍
  • Oracle 19c PDB克隆后出现Warning: PDB altered with errors受限模式处理
  • 阿里云ACK容器如何配置pod分散在集群的不同节点上
  • Qt信号和槽
  • Python知识点精汇!字符串:定义、截取(索引)和其内置函数
  • 【CV】头盔检测区域入侵项目
  • 大数据应用开发——实时数据处理(一)
  • Wireshark中的length栏位
  • IDEA中创建多模块项目步骤
  • 深度学习笔记13-卷积神经网络1
  • 【新华妙笔-注册/登录安全分析报告-无验证方式导致安全隐患】
  • STM32电源管理—实现低功耗
  • 【链路层】空口数据包详解(4):数据物理通道协议数据单元(PDU)
  • 数学分组求偶数和
  • 机器学习基础02_特征工程
  • CSS Modules中的 :global
  • linux病毒编写+vim shell编程
  • WinDefender Weaker
  • 智能工厂的设计软件 为了监管控一体化的全能Supervisor 的监督学习 之 序5 架构for认知系统 总述 (架构全图)
  • vmware集群 vSAN HCL 数据库
  • 人工智能引发直播革命:AI 技术塑造无人直播全新体验
  • 数据研发基础 | 什么是流批一体
  • 《Python网络安全项目实战》项目6 编写密码工具程序
  • 现代C++HTTP框架cinatra