Rust 中逆变使用的一个例子是什么? [英] What is an example of contravariant use in Rust?

查看:37
本文介绍了Rust 中逆变使用的一个例子是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Nomicon 关于子类型的部分中,它说逆变可用于函数指针类型.但是,我找不到任何很好的例子.我试图用函数指针编写一个结构体,但逆变似乎不起作用.

这是什么代码示例?

解决方案

Rust 的子类型概念仅适用于生命周期.

<小时>

您链接的页面上搜索术语contra" 有许多相关的段落:

<块引用>

实际上在 Rust 中见证逆变是相当困难的,尽管它确实存在.

<块引用>

注意:语言中唯一的逆变源是函数的参数,这就是为什么它在实践中很少出现.调用逆变涉及使用函数指针进行高阶编程,这些函数指针接受具有特定生命周期的引用(而不是通常的任何生命周期",后者进入更高级别的生命周期,独立于子类型工作).

<块引用>

这就是为什么函数类型与语言中的其他任何东西不同,它们的参数是逆变的.

本页以所有类型逆变的示例结束.应用它...

逆变

struct MyContraType{k1: fn(Mixed),//在混合上逆变}fn contra_example<'short>(mut a: MyContraType<&'short u8>,mut b: MyContraType<&'static u8>,x: fn(&'short u8),y: fn(&'static u8),){a.k1 = x;a.k1 = y;//失败b.k1 = x;b.k1 = y;}

逆变示例不允许将 'static 替换为 'short:

错误[E0308]:类型不匹配-->src/lib.rs:12:12|12 |a.k1 = y;|^ 终生不匹配|= 注意:预期类型`fn(&'short u8)`找到类型`fn(&'static u8)`注意:生命周期 'short 在 5:19 在函数体上定义...-->src/lib.rs:5:19|5 |fn contra_example<'short>(|^^^^^^= 注意:...不一定比静态生命周期长

协方差

struct MyCoType{k1: fn() ->Mixed,//在 Mixed 上的协变}fn co_example<'short>(mut a: MyCoType<&'short u8>,mut b: MyCoType<&'static u8>,x: fn() ->&'短u8,y: fn() ->&'静态u8,){a.k1 = x;a.k1 = y;b.k1 = x;//失败b.k1 = y;}

协变示例不允许将 'short 替换为 'static:

错误[E0308]:类型不匹配-->src/lib.rs:29:12|29 |b.k1 = x;|^ 终生不匹配|= 注意:预期类型`fn() ->&'静态u8`找到类型`fn() ->&'短u8`注意:生命周期 'short 在 21:15 在函数体上定义......-->src/lib.rs:21:15|21 |fn co_example<'short>(|^^^^^^= 注意:...不一定比静态生命周期长

In the Nomicon's section about subtyping, it says contravariance is available for a function pointer type. However, I can't find any good examples of this. I tried to code a struct with a function pointer, but the contravariance doesn't seem to work.

What is a code example of this?

解决方案

Rust's notion of subtyping only applies to lifetimes.


Searching for the term "contra" on the page you linked has numerous relevant paragraphs:

Actually witnessing contravariance is quite difficult in Rust, though it does in fact exist.

NOTE: the only source of contravariance in the language is the arguments to a function, which is why it really doesn't come up much in practice. Invoking contravariance involves higher-order programming with function pointers that take references with specific lifetimes (as opposed to the usual "any lifetime", which gets into higher rank lifetimes, which work independently of subtyping).

And that's why function types, unlike anything else in the language, are contravariant over their arguments.

The page ends with an example of all the types of contravariance. Applying it...

Contravariance

struct MyContraType<Mixed> {
    k1: fn(Mixed), // contravariant over Mixed
}

fn contra_example<'short>(
    mut a: MyContraType<&'short u8>,
    mut b: MyContraType<&'static u8>,
    x: fn(&'short u8),
    y: fn(&'static u8),
) {
    a.k1 = x;
    a.k1 = y; // Fails
    b.k1 = x;
    b.k1 = y;
}

The contravariant example does not allow substituting 'static for 'short:

error[E0308]: mismatched types
  --> src/lib.rs:12:12
   |
12 |     a.k1 = y;
   |            ^ lifetime mismatch
   |
   = note: expected type `fn(&'short u8)`
              found type `fn(&'static u8)`
note: the lifetime 'short as defined on the function body at 5:19...
  --> src/lib.rs:5:19
   |
5  | fn contra_example<'short>(
   |                   ^^^^^^
   = note: ...does not necessarily outlive the static lifetime

Covariance

struct MyCoType<Mixed> {
    k1: fn() -> Mixed, // covariant over Mixed
}

fn co_example<'short>(
    mut a: MyCoType<&'short u8>,
    mut b: MyCoType<&'static u8>,
    x: fn() -> &'short u8,
    y: fn() -> &'static u8,
) {
    a.k1 = x;
    a.k1 = y;
    b.k1 = x; // Fails
    b.k1 = y;
}

The covariant example does not allow substituting 'short for 'static:

error[E0308]: mismatched types
  --> src/lib.rs:29:12
   |
29 |     b.k1 = x;
   |            ^ lifetime mismatch
   |
   = note: expected type `fn() -> &'static u8`
              found type `fn() -> &'short u8`
note: the lifetime 'short as defined on the function body at 21:15...
  --> src/lib.rs:21:15
   |
21 | fn co_example<'short>(
   |               ^^^^^^
   = note: ...does not necessarily outlive the static lifetime

这篇关于Rust 中逆变使用的一个例子是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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