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

RUST 每日一省:泛型约束——trait

        使用泛型编程时, 很多情况下的行为并不是针对所有类型都实现的,用trait作为泛型的约束。例如,我们编写一个判断两个变量大小的泛型函数,编译时,会运行如下错误。

fn max<T>(a: T, b: T) -> T {
    if a < b {
        b
    } else {
        a
    }
} 

fn main() {
    let m = max(1, 2);
}


error[E0369]: binary operation `<` cannot be applied to type `T`
  --> src/main.rs:14:10
   |
14 |     if a < b {
   |        - ^ - T
   |        |
   |        T
   |
help: consider restricting type parameter `T`
   |
13 | fn max<T: std::cmp::PartialOrd>(a: T, b: T) -> T {
   |         ++++++++++++++++++++++

        这个编译错误是说, 由于泛型参数T没有任何约束——如果我们填入两个Struct类型,如何比较呢, 因此编译器认为a<b这个表达式是不合理的, 因为它只能作用于支持比较运算符的类型。编译器也进行了提示,只有impl了PartialOrd的类型, 才能支持比较运算符。修正如下。

fn max<T:PartialOrd>(a: T, b: T) -> T {
    if a < b {
        b
    } else {
        a
    }
} 

fn main() {
    let m = max(1, 2);
    
}

trait约束语法

trait约束的语法如下:
fn generic<T: MyTrait + MyOtherTrait + SomeStandarTrait>(t: T)
{

        todo!()

}
 

        如果泛型参数有多个trait约束,通过+语法来指定多个trait约束;拥有多个泛型参数的函数,在函数名和参数列表之间会有很长的trait约束信息,使得函数签名可读性差。Rust提供where关键字来处理这种情况。代码如下,

fn max<T>(a: T, b: T) -> T
    where T: PartialOrd
{
    if a < b {
        b
    } else {
        a
    }
}

总结,泛型参数约束有两种语法:
(1) 在泛型参数声明的时候使用冒号: 指定;
(2) 使用where子句指定。

fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U) -> i32 {}

fn some_function<T, U>(t: T, u: U) -> i32
where T: Display + Clone,
U: Clone + Debug
{}

        在有了“泛型约束”之后, 编译器不仅会在声明泛型的地方做类型检查, 还会在调用的地方做类型检查。例如当用户调用时,编译器会分析泛型函数当场检查类型的合法性,此时泛型的类型检查就完成了。

fn max<T:PartialOrd>(a: T, b: T) -> T {
    if a < b {
        b
    } else {
        a
    }
} 

struct T1 {
    value: i32
}

#[derive(PartialOrd,PartialEq)]
struct T2 {
    value: i32
}

fn main() {
    let m = max(1, 2);
    let t11 = T1{value:1};
    let t12 = T1{value:1};
    let m = max(t11, t12);

    let t21 = T2{value:1};
    let t22 = T2{value:1};
    let m = max(t21, t22);
    
}

   = help: the trait `PartialOrd` is not implemented for `T1`
note: required by a bound in `max`
  --> src/main.rs:31:10
   |
31 | fn max<T:PartialOrd>(a: T, b: T) -> T {
   |          ^^^^^^^^^^ required by this bound in `max`
help: consider annotating `T1` with `#[derive(PartialOrd)]`
   |
3  | #[derive(PartialOrd)]
   |

        我们看到定时泛型函数max时指定了PartialOrd,没有错误;但是在我们调用的时候,由于T1没有实现PartialOrd,导致调用失败了。


http://www.kler.cn/news/17140.html

相关文章:

  • Java面试题JVM JDK 和 JRE
  • 9:00进去,9:05就出来了,这问的也太···
  • 麻雀键值数据库开发日志
  • Linux常用的压缩、解压缩以及scp远程传输命令的使用
  • Android中Paint字体的灵活使用
  • 如何将 Elasticsearch 和时间序列数据流用于可观察性指标 - 8.7
  • 宏观经济笔记--CPI和PPI
  • 使用rt thread studio新建一个rt thread工程的详细操作说明(以stm32F411CEU6)为例
  • Python---多线程编程、基于Socket完成服务端程序开发、基于Socket完成客户端程序开发
  • SpringMVC详细介绍和@RequestMapping详细使用说明
  • 预制菜,巨头们的新赛场
  • python3 强制使用任意父级相对导入,越过python相对导入限制,拒绝 ImportError
  • 操作系统——设备管理
  • kafka的安装与使用
  • 关于低代码开发平台的一些想法
  • 【Frame.h】
  • 手写堆priority_queue优先队列
  • 题目:16版.学生-成绩关联实体
  • Centos7快速安装Kibana并连接ES使用
  • 结合SSE实现实时位置展示与轨迹展示
  • 区块链系统探索之路:基于椭圆曲线的私钥与公钥生成
  • FPGA/Verilog HDL/AC620零基础入门学习——8*8同步FIFO实验
  • spring-模型数据和视图---视图解析器的说明以及大量代码演示
  • AUTOSAR知识点Com(十三):ComM内容分析
  • 后端程序员的前端必备【Vue】- 01 Vue入门
  • 计算机Z20-第7-8周作业
  • 17. Pod 自动管理——DeamonSet 和 Job
  • JDK8 中Arrays.sort() 排序方法解读
  • MySQL高阶——索引设计的推演
  • Redis-集合(Set)