为什么惰性静态值声称没有实现它明确实现的特征? [英] Why does a lazy-static value claim to not implement a trait that it clearly implements?

查看:23
本文介绍了为什么惰性静态值声称没有实现它明确实现的特征?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下代码(尝试使用 reqwest crate 发出 HTTP 请求),编译器说我的值 SID_URI 没有实现特征 PolyfillTryInto.这里发生了什么?reqwest::Url 明确实现私有特性 reqwest::into_url::PolyfillTryInto.

With the following code (an attempt to make an HTTP request using the reqwest crate), the compiler says that my value SID_URI does not implement the trait PolyfillTryInto. What's going on here? reqwest::Url clearly implements the private trait reqwest::into_url::PolyfillTryInto.

#[macro_use]
extern crate lazy_static;
extern crate reqwest;

static R_EMAIL: &str = "example@example.com";
static R_PASS: &str = "password";
static API_PUBKEY: &str = "99754106633f94d350db34d548d6091a";
static API_URI: &str = "https://example.com";
static AUTH_PATH: &str = "/api/v1";

lazy_static! {
    static ref SID_URI: reqwest::Url = reqwest::Url::parse(&(API_URI.to_owned() + AUTH_PATH)).unwrap();
}

fn get_sid() -> Result<reqwest::Response, reqwest::Error> {
    let client = reqwest::Client::new();
    let params = [("ID", R_EMAIL), ("PW", R_PASS), ("KY", API_PUBKEY)];
    let q = client.post(SID_URI).form(&params).send()?;
    Ok(q)
}

fn main() {
    assert!(get_sid().is_ok());
}

error[E0277]: the trait bound `SID_URI: reqwest::into_url::PolyfillTryInto` is not satisfied
  --> src/main.rs:19:20
   |
19 |     let q = client.post(SID_URI).form(&params).send()?;
   |                    ^^^^ the trait `reqwest::into_url::PolyfillTryInto` is not implemented for `SID_URI`
   |
   = note: required because of the requirements on the impl of `reqwest::IntoUrl` for `SID_URI`

推荐答案

编译器不会骗你,你只是跳过了错误消息的相关细节.这是一个独立的示例:

The compiler isn't lying to you, you are just skipping over a relevant detail of the error message. Here's a self-contained example:

#[macro_use]
extern crate lazy_static;

struct Example;
trait ExampleTrait {}
impl ExampleTrait for Example {}

lazy_static! {
    static ref EXAMPLE: Example = Example;
}

fn must_have_trait<T>(_: T)
where
    T: ExampleTrait,
{
}

fn main() {
    must_have_trait(EXAMPLE);
    must_have_trait(42i32);
}

error[E0277]: the trait bound `EXAMPLE: ExampleTrait` is not satisfied
  --> src/main.rs:19:5
   |
19 |     must_have_trait(EXAMPLE);
   |     ^^^^^^^^^^^^^^^ the trait `ExampleTrait` is not implemented for `EXAMPLE`
   |
   = note: required by `must_have_trait`

error[E0277]: the trait bound `i32: ExampleTrait` is not satisfied
  --> src/main.rs:20:9
   |
20 |         must_have_trait(42i32);
   |         ^^^^^^^^^^^^^^^ the trait `ExampleTrait` is not implemented for `i32`
   |
   = note: required by `must_have_trait`

比较两条错误信息:

the trait bound `EXAMPLE: ExampleTrait` is not satisfied
the trait bound `i32: ExampleTrait` is not satisfied

第二条错误消息不是说42没有实现ExampleTrait,而是说i32缺乏执行力.此错误消息显示失败的类型,而不是值的名称!这意味着相同上下文中的 EXAMPLE 指的是一个类型.

The second error message doesn't say that 42 does not implement ExampleTrait, it says that i32 lacks the implementation. This error message shows the type that fails, not the name of the value! That means that EXAMPLE in the same context is referring to a type.

Lazy-static 通过创建一次性类型value 并提供线程安全的单一初始化保证:

Lazy-static works by creating one-off types that wrap your value and provide thread-safe single initialization guarantees:

对于给定的 static ref NAME: TYPE = EXPR;,宏会生成一个实现 Deref 的唯一类型,并将其存储在名为 <代码>名称.

For a given static ref NAME: TYPE = EXPR;, the macro generates a unique type that implements Deref<TYPE> and stores it in a static with name NAME.

这个包装类型没有实现你的特征,只有包装类型可以.您将需要调用 Deref 然后可能重新引用它以获取 &Url,假设对 Url 的引用实现你的特点:

This wrapper type does not implement your trait, only the wrapped type does. You will need to invoke Deref and then probably re-reference it to get to a &Url, assuming that a reference to a Url implements your trait:

must_have_trait(&*EXAMPLE);

此外,使用裸静态变量会尝试将其移出静态位置(这将是一件非常糟糕的事情),因此您始终需要通过引用来使用它.

Additionally, using the bare static variable would attempt to move it out of the static location (which would be a Very Bad Thing), so you always need to use it by reference.

这篇关于为什么惰性静态值声称没有实现它明确实现的特征?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆