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

揭秘rust中默认参数类型不为人知的秘密,你确定不来了解下吗?

在 Rust 中,你可以为泛型类型参数指定默认类型参数,这样在调用函数或结构体时,如果没有指定具体的类型参数,就会使用默认的类型参数。这提供了一种灵活的方式来使用泛型代码,同时保持了代码的简洁性和可读性。在使用过程中不用考虑泛型带来传入具体参数的问题。

基本语法

默认类型参数的语法是在泛型类型参数后面加上 = 和一个默认值:

  • 在trait中指定默认类型参数

trait Add<Rhs = Self>{
  type Output;
    
  #[must_use]
  fn add(self, rhs: RHS) -> Self::Output;
}

这里Add<RHS = Self>是默认泛型类型参数,表示如果不显示指定泛型类型,就默认泛型类型为Self。当使用泛型类型参数时,可以为泛型指定一个默认的具体类型。如果默认类型就足够的话,这消除了为具体类型实现 trait 的需要。为泛型类型指定默认类型的语法是在声明泛型类型时使用 <PlaceholderType=ConcreteType>。

  • 在结构体中指定默认类型参数

struct Stack<T = i32> {
    items: Vec<T>,
}

用法示例

  • trait的默认类型参数

pub trait Watch<Inner=String> {
    type Item;
    fn inner(&self) -> Option<Self::Item>;
    fn info(&self) -> Inner;
}

struct A {
    data: i32,
}

impl Watch<i32> for A {
    type Item = i32;
    fn inner(&self) -> Option<Self::Item> {
        Some(self.data)
    }
    fn info(&self) -> i32 {
        println!("A inner is {}", self.data);
        self.data
    }
}

struct B {
    data: String,
}

impl Watch for B {
    type Item = String;
    fn inner(&self) -> Option<Self::Item> {
        Some(self.data.clone())
    }
    fn info(&self) -> String {
        println!("B inner is {}", self.data);
        self.data.clone()
    }
}

fn call_trait_default_param_type(){
  let a = A{data: 10};
  let b = B{data: String::from("B")};
  assert_eq!(10, a.info());
  assert_eq!(Some(String::from("B")), b.inner());
}

我们在上述的例子中我们创建了一个Watchtrait里面的默认类型为String,trait中定义了一个关联变量Item和两个函数分别是innerinfo。 再创建一个结构体B,里面包含一个字段类型是String,为结构体B实现trait Watch并把关联类型设置为String,分别实现trait中定义的两个函数。在main函数中创建两个结构体实例,分别调用实现了trait的两个方法。

  • 结构体中默认参数类型

struct Stack<T = i32> {
    items: Vec<T>,
}

impl<T> Stack<T> {
    fn new() -> Self {
        Stack { items: Vec::new() }
    }
}

impl Stack<i32> {
    fn new_with_int() -> Self {
        Stack { items: vec![1, 2, 3] }
    }
}

fn main() {
    let stack_default: Stack<i32> = Stack::new(); // 使用默认类型参数 i32
    let int_stack = Stack::new_with_int(); // 明确指定 i32 类型参数
}

上述代码中我们创建一个泛型结构体Stack,其中该泛型结构体的默认参数类型是i32类型。接着我们实现不指定泛型参数类型的函数new和指定默认类型的new_with_int函数。然后在main函数中调用上述方法。

使用场景

  1. 提供默认行为:当你想要提供一个通用的函数或结构体时,可以为不经常变化的参数提供默认值。

  2. 简化函数调用:在大多数情况下,如果有一个常用的类型,你可以让函数调用者不必每次都指定类型参数。

  3. 保持向后兼容:当你更新库或 API 时,添加新的泛型参数并为它们提供默认值可以避免破坏现有代码。

注意事项

默认参数类型智能在结构体,枚举,trait以及type中使用,不能在函数中使用默认类型参数。


http://www.kler.cn/a/380828.html

相关文章:

  • zabbix监控山石系列Hillstone监控模版(适用于zabbix7及以上)
  • 菜鸟带新鸟——基于EPlan2022的部件库制作
  • CASA(Carnegie-Ames-Stanford Approach) 模型原理及实践
  • SpringBoot 自动装配原理及源码解析
  • 定位方式:css
  • layui动态拼接生成下拉框验证必填项失效问题
  • Java 基于SpringBoot+Vue 的公交智能化系统,附源码、文档
  • Django Form 实现多层(嵌套)模型表单
  • 深度学习模块创作(缝合)教程|适合1-360月小宝宝食用,干货满满
  • 深度学习基础知识-损失函数
  • 【C/C++】memcpy函数的模拟实现
  • Mac OS 配置Docker+Mysql
  • C++中的继承——第一篇
  • ​CSS之三
  • 【OJ题解】C++实现字符串大数相乘:无BigInteger库的字符串乘积解决方案
  • vue中强制更新视图
  • 网络信息系统的整个生命周期
  • 服务器作业2
  • AUTOSAR COM 模块的主要功能导读以及示例
  • 【jvm】如何设置Eden、幸存者者区的比例
  • C语言 | Leetcode C语言题解之第521题最长特殊序列I
  • C++模拟实现list
  • NRF52832学习笔记(41)——添加串口库libuarte
  • GPT-SoVITS 部署方案
  • sqlalchemy连接mysql数据库
  • 全面解析:大数据技术及其应用