当前位置: 首页 > 知识库问答 >
问题:

在泛型函数中是否只有基元类型才有一个特性?

太叔繁
2023-03-14

我试图写一个通用函数,它将尝试将字符串转换为数字类型,如i32f64等。如果字符串不可转换,那么它将返回0。我正在寻找一个适当的特性绑定到我下面的通用函数中使用:

use std::str::FromStr;

fn get_num_from_str<T: FromStr>(maybe_num_str: &String) -> T {
    let maybe_num = T::from_str(maybe_num_str.as_str());
    if maybe_num.is_ok() {
        return maybe_num.unwrap();
    }
    0 as T
}

fn main() {
    let num_str = String::from("12");
    println!("Converted to i32: {}", get_num_from_str::<i32>(&num_str));
}

游乐场链接

我发现Rust有一个Primitive特征,在它被删除之前。现在还有别的东西可以代替吗?

我找到了一个变通方法:

use std::str::FromStr;

fn get_num_from_str<T: Default + FromStr>(maybe_num_str: &String) -> T {
    let maybe_num = T::from_str(maybe_num_str.as_str());
    maybe_num.unwrap_or(Default::default())
}

游乐场链接

正如trait绑定所建议的,这应该适用于同时具有DefaultFromStr实现的任何函数,我应该重命名函数以反映这一点,但是,如果知道基本数字类型是否有任何特征,我可以使用这些特征来确保这个函数不能用于数字类型以外的任何其他类型,那还是很好的。

共有2个答案

穆浩皛
2023-03-14

不,没有这种特质。为什么啊?因为Rust不需要像大多数其他语言那样关心区分“原语”和“非原语”。现实地说,为什么要这样?

另外,请注意数组和原始指针也是原语;你真的希望包括这些吗?

我可以使用它来确保此函数不能用于除数字类型以外的任何其他类型。

你为什么要人为地限制你可以使用什么类型?为什么您的函数不能与任何满足其基本标准的类型一起工作?你想保护自己不受谁的伤害?

您的示例可以缩短:

fn get_num_from_str<T: Default + FromStr>(s: &str) -> T {
    s.parse().unwrap_or_default()
}
  • 为什么不鼓励接受对字符串的引用(
韩嘉祯
2023-03-14

Num板条箱中定义的Num特性应该满足您的需求,但您尝试的操作在Rust中并不惯用,因此我想提供两个建议:

  1. 例如,在某些语言(如C语言)中,传统的做法是用特殊的含义重载特定的值(如0或-1),但这已被证明是一个混乱的根源,甚至是硬bug

取而代之,考虑使用<代码>结果

在您的情况下,可能需要使用结果

有了以上两条信息,您的代码现在可以更稳健地重写如下(使用Rust 1.26来简化错误处理):

type Result<T> = std::result::Result<T, Box<std::error::Error>>;

fn main() -> Result<()> {
    let num_str = String::from("12");
    println!("Converted to i32: {}", num_str.parse::<i32>()?);
    Ok(())
}

操场示例

如果出现问题,请注意报告错误的程度:

type Result<T> = std::result::Result<T, Box<std::error::Error>>;

fn main() -> Result<()> {
    let num_str = "-1";
    println!("Invalid u32 conversion: {}", num_str.parse::<u32>()?);
    Ok(())
}

操场示例

这会将Error:parseInteror{kind:InvalidDigit}打印到控制台,并将值std::libc::EXIT_FAILURE返回到调用进程(表示程序带错误退出),所有这些都不需要任何值重载或“幻数”。

 类似资料:
  • 我在typescript中有以下泛型类 但是我不知道为什么得到这个错误Class'(匿名类)'不正确地扩展基类'列'。属性getValue的类型不兼容。类型'(值:数字)=

  • 我有一个(相当复杂的)数据类型: 现在我发现自己需要另一个数据类型…有两个构造函数。一个与的相同;另一个只存储一个。我有什么选择? 虽然这会起作用,但它也允许类似这样的东西,这是没有意义的。

  • 如果方法定义为: 第一个T加什么?因为它与以下内容基本相同:

  • 我想使返回数据类型的的函数与传入的参数的数据类型相同。例如,我会这样调用函数: 因为我将一个传递给,所以它返回了一个

  • (沙盒) 获取此错误: 类型“number”不可分配给类型“T”“number”可分配给“T”类型的约束,但“T”可以用约束{}的不同子类型实例化。(2322)输入。ts(1,26):预期类型来自此签名的返回类型。 我希望typescript能够自动推断T为数字,然后直接使用它。为什么它在抱怨?写这样的东西的正确方法是什么?谢谢

  • 问题内容: 我是Java泛型的新手,来自.NET世界,我习惯于编写这样的方法: 该方法接受通用类型的对象,并检查该对象是否实现通用接口的 特定 版本,在这种情况下为。 现在,在Java中,我可以执行以下操作: 但 Java并 没有 让我做 据我所知,由于类型擦除,通常在Java中,此类将由类对象处理,我们将执行以下操作: 但是由于我要检查的类型是通用接口,所以您不能这样做: 那么,如何在Java中