Почему псевдоним типа не может использовать связанные константы из исходного типа в Rust? - PullRequest
3 голосов
/ 01 июля 2019

У меня есть псевдоним типа type CardId = u64;, и я хочу инициализировать его максимальным числом, которое он может иметь через константу std::u64::MAX. И был удивлен, узнав, что я не могу сделать то же самое из псевдонима.

use std::u64;

type CardId = u64;

fn main() {
    let this_works = u64::MAX;
    let this_doesnt_work = CardId::MAX;

    println!("Max amount in integer: {} and {}", this_works, this_doesnt_work);
}

(Постоянная ссылка на игровую площадку)

Я ожидал, что константа MAX также будет доступна из псевдонима типа. Это помогло бы мне, когда я изменил бы тип на u32, и это заставило бы код иметь две точки, где мне нужно было бы изменить вместо просто местоположения псевдонима типа. Почему было принято это решение, и я что-то упустил, что, возможно, сделало бы это возможным?

Ответы [ 2 ]

7 голосов
/ 01 июля 2019

Константы, такие как std::u64::MAX, не являются связанными константами типа u64, но константы, определенные в модуле с именем u64.

Это наследие, когда у Rust не было связанных констант. В настоящее время существует RFC, открытый для их устаревания .

«Новый» способ сделать это - использовать связанные const методы, которые доступны через псевдонимы типов:

use std::u64;

type CardId = u64;

fn main() {
    let this_works = u64::max_value();
    let this_also_work = CardId::max_value();

    println!(
        "Max amount in integer: {} and {}",
        this_works, this_also_work
    );
}

(Постоянная ссылка на игровую площадку)

Связанные константы также доступны через псевдонимы типов, как вы ожидаете:

struct Foo;

impl Foo {
    const FOO: u32 = 42;
}

type Bar = Foo;

fn main() {
    let this_works = Foo::FOO;
    let this_also_work = Bar::FOO;

    println!("The answer: {} and {}", this_works, this_also_work);
}

(Постоянная ссылка на игровую площадку)

6 голосов
/ 01 июля 2019

Это потому, что std::u64::MAX является константой модуля, а не константой типа.

Вы можете использовать max_value, если хотите использовать его с псевдонимом типа:

use std::u64;

type CardId = u64;

fn main() {
    let this_works = u64::max_value();
    let this_does_work_as_well = CardId::max_value();

    println!("Max amount in integer: {} and {}", this_works, this_does_work_as_well);
}
...