< 返回版块

cybertheye 发表于 2024-03-23 23:28

Tags:rust,convert

use std::convert::TryInto;

fn main() {
  let a: i32 = 10;
  let b: u16 = 100;

  let b_ = b.try_into()
            .unwrap();

  if a < b_ {
    println!("Ten is less than one hundred.");
  }
}

这个代码里面,是不是因为 a<b_ ,然后编译器去推导 b.try_into() 转成什么类型

但我看了一下 u16实现的try_into

// TryFrom implies TryInto
#[stable(feature = "try_from", since = "1.34.0")]
impl<T, U> TryInto<U> for T
where
    U: TryFrom<T>,
{
    type Error = U::Error;

    #[inline]
    fn try_into(self) -> Result<U, U::Error> {
        U::try_from(self)
    }
}
}

这里有懂的可以解释一下吗,上面泛型U在let b_ = b.try_into().unwrap();是啥

评论区

写评论
ankoGo 2024-03-25 10:48

楼下牛皮

aj3n 2024-03-25 01:00

因为std::cmp::PartialOrd/Ord的签名是fn cmp(&Self, &Self) -> ..., 所以能从下面的比较表达式历里推断出b_的类型和a一样,你也意识到了; 对应的,如果把比较表达式改成a - b_ < 0, 你会发现推断失效了,主要因为std::ops::Sub的约束不一样,感兴趣可以翻文档看看; 实践上写完发现推断不出类型补上就好了,没必要特别深究;

显然的,U就是i32, 但是这个实现路径还是挺绕的,大概是这四个:

impl<T, U> TryInto<U> for T where  U: TryFrom<T>;
impl<T, U> TryFrom<U> for T where U: Into<T>;
impl<T, U> Into<U> for T where U: From<T>;
impl From<u16> for i32;

需要注意的是所有From/TryFrom都能自动派生出对应的Into/TryInto,但反过来不行(语言表达能力限制?), 所以实践上应该优先实现From/TryFrom; 一般不会遇到跳这么几层的,大概看看就好,当熟悉标准库了;

Bai-Jinlin 2024-03-24 11:11

U当然是i32呀,因为下面那个比较推导出了类型

1 共 3 条评论, 1 页