Выбрать главу

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Утверждения where также могут использоваться для применения ограничений в некоторых случаях, чтобы добавить выразительности.

std::fmt, struct и trait

Следствием того, как работают ограничения по трейту, является то, что даже если трейт не включает в себя какие-либо функциональные возможности, вы все равно можете использовать его в качестве ограничения. Примерами таких трейтов являются Eq и Ord из стандартной библиотеки.

struct Cardinal;

struct BlueJay;

struct Turkey;

trait Red {}

trait Blue {}

impl Red for Cardinal {}

impl Blue for BlueJay {}

// Эти функции действительны только для типов реализующих эти типажи.

// То, что типажи пусты, не имеет значения.

fn red<T: Red>(_: &T) -> &'static str { "красная" }

fn blue<T: Blue>(_: &T) -> &'static str { "синяя" }

fn main() {

let cardinal = Cardinal;

let blue_jay = BlueJay;

let _turkey = Turkey;

// `red()` не будет работать для blue_jay, ни наоборот,

// из-за ограничений по трейту.

println!("Кардинал {} птица", red(&cardinal));

println!("Голубая сойка {} птица", blue(&blue_jay));

//println!("Индюк {} птица", red(&_turkey));

// ^ TODO: Попробуйте раскомментировать эту строку.

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

std::cmp::Eq, std::marker::Copy и трейты

Множественные ограничения по типажу могут быть применены с помощью +. Разные типы разделяются с помощью ,.

use std::fmt::{Debug, Display};

fn compare_prints<T: Debug + Display>(t: &T) {

println!("Debug: `{:?}`", t);

println!("Display: `{}`", t);

}

fn compare_types<T: Debug, U: Debug>(t: &T, u: &U) {

println!("t: `{:?}", t);

println!("u: `{:?}", u);

}

fn main() {

let string = "words";

let array = [1, 2, 3];

let vec = vec![1, 2, 3];

compare_prints(&string);

//compare_prints(&array);

// ЗАДАНИЕ ^ Попробуйте удалить комментарий.

compare_types(&array, &vec);

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

std::fmt и trait

Ограничение типажа также может быть выражено с помощью утверждения where непосредственно перед открытием {, а не при первом упоминании типа. Кроме того, утверждения where могут применять ограничения типажей к произвольным типам, а не только к параметрам типа.

В некоторых случаях утверждение where является полезным:

   • При указании обобщённых типов и ограничений типажей отдельно, код становится более ясным:

impl <A: TraitB + TraitC, D: TraitE + TraitF> MyTrait<A, D> for YourType {}

// Выражение ограничений типажей через утверждение `where`

impl <A, D> MyTrait<A, D> for YourType where

A: TraitB + TraitC,

D: TraitE + TraitF {}

   • Использование утверждения where более выразительно, чем использование обычного синтаксиса. В этом примере impl не может быть непосредственно выражен без утверждения where: