Что является примером контравариантного использования в Rust? - PullRequest
0 голосов
/ 25 марта 2019

В разделе Nomicon о подтипе говорится, что для типа указателя функции доступна контрастность. Однако я не могу найти хороших примеров этого. Я пытался закодировать структуру с помощью указателя на функцию, но, похоже, противоречивость не работает.

Что такое пример кода?

1 Ответ

5 голосов
/ 25 марта 2019

Понятие подтипа в Rust применимо только к временам жизни .


В поиске термина "contra" на на странице, на которую вы ссылались , есть множество соответствующих абзацев:

На самом деле свидетельствование контравариантности в Rust довольно сложно, хотя в действительности оно существует.

ПРИМЕЧАНИЕ. Единственным источником контравариантности в языке являются аргументы функции, поэтому она практически не используется на практике. Вызов контравариантности включает в себя программирование более высокого порядка с указателями функций, которые принимают ссылки с определенным временем жизни (в отличие от обычного «любого времени жизни», которое попадает в времена жизни более высокого ранга, которые работают независимо от подтипа).

И именно поэтому типы функций, в отличие от всего, что есть в языке, противоречивы по отношению к своим аргументам.

Страница заканчивается примером всех типов контравариантности. Применяя это ...

контрвариация

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;
}

Контравариантный пример не позволяет заменить 'static на '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

ковариации

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;
}

Ковариантный пример не позволяет заменить 'short на '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
...