gpt4 book ai didi

rust - 如果我为引用类型实现 `TryFrom`,为什么在 Rust 中不会发生自动借用?

转载 作者:行者123 更新时间:2023-12-04 17:07:32 25 4
gpt4 key购买 nike

假设我想对引用实现转换。在这种情况下,它是从 &f64 -> Foo 的转换.

use std::convert::{TryFrom, TryInto};

struct Foo {
a: f64
}

impl TryFrom<&f64> for Foo {
type Error = String;

fn try_from(value: &f64) -> Result<Foo, String> {
Ok(Foo {
a: *value
})
}
}

fn main(){
let foo: Foo = 5.0.try_into().unwrap();
let bar: Foo = (&5.0).try_into().unwrap();
}
(是的,当然这是一个毫无意义和愚蠢的例子,但它有助于简化问题)
现在,主要方法中的第二行,手动借用,成功。
但是,没有手动借用的 main 方法中的第一行失败并显示以下错误:
error[E0277]: the trait bound `Foo: From<{float}>` is not satisfied
--> src/main.rs:18:24
|
18 | let foo: Foo = 5.0.try_into().unwrap();
| ^^^^^^^^ the trait `From<{float}>` is not implemented for `Foo`
|
= note: required because of the requirements on the impl of `Into<Foo>` for `{float}`
note: required because of the requirements on the impl of `TryFrom<{float}>` for `Foo`
--> src/main.rs:7:6
|
7 | impl TryFrom<&f64> for Foo {
| ^^^^^^^^^^^^^ ^^^
= note: required because of the requirements on the impl of `TryInto<Foo>` for `{float}`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error
Playground
为什么自动借阅在这里不起作用?

最佳答案

正如错误消息所暗示的那样,问题是 the trait bound Foo: From<{float}> is not satisfied .匹配 trait 时,Rust 不会执行任何强制,但 探索合适的方法 .这实际上记录在 The Rustonomicon 中, 读

Note that we do not perform coercions when matching traits (except for receivers, see the next page). If there is an impl for some type U and T coerces to U, that does not constitute an implementation for T.


next page

Suppose we have a function foo that has a receiver (a self, &self or &mut self parameter). If we call value.foo(), the compiler needs to determine what type Self is before it can call the correct implementation of the function. ... If it can't call this function (for example, if the function has the wrong type or a trait isn't implemented for Self), then the compiler tries to add in an automatic reference. This means that the compiler tries <&T>::foo(value) and <&mut T>::foo(value). This is called an "autoref" method call.


因此,当匹配 trait bound 时,Rust 编译器将尝试仅在类型上自动引用/取消引用。此外,rust 中的点运算符只是完全限定函数调用的语法糖。因此 5.0.try_into().unwrap();会变成 f64::try_into(5.0).unwrap();TryInto未针对 f64 实现, Rust 将尝试通过调用 &f64::try_into(5.0).unwrap(); 来自动引用它.现在编译器可以找到 TryInto的版本为 &f64 实现,但是参数的类型仍然不匹配: try_into&f64需要 &f64作为参数类型,而当前调用提供 f64 , 并且 Rust 编译器在检查 trait bound 时不能对参数进行任何强制。因此特征边界仍然不匹配( &f64 不能接受 f64 参数)并且检查失败。因此,您将看到错误消息。

关于rust - 如果我为引用类型实现 `TryFrom`,为什么在 Rust 中不会发生自动借用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70232764/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com