Trait Bound

impl syntax

fn double<T>(x: impl Add<Output = T> + Copy) -> T {
    x + x
}

Trait Bound Syntax

fn double_2<T: Add<Output = T> + Copy>(x: T) -> T {
    x + x
}

fn add<T: Add<Output = T>>(x: T, y: T) -> T {
    x + y
}

Trait Bound with where clause Trait Bound Syntax

fn double_3<T>(x: T) -> T
where
    T: Add<Output = T> + Copy,
{
    x + x
}

fn add_2<T>(x: T, y: T) -> T
where
    T: Add<Output = T>,
{
    x + y
}

fn foo<A, B>(x: A, y: B) -> i32
where
    A: Display + Clone,
    B: Debug + Clone,
{
    unimplemented!()
}

complete source code of above

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

fn double<T>(x: impl Add<Output = T> + Copy) -> T {
    x + x
}

fn double_2<T: Add<Output = T> + Copy>(x: T) -> T {
    x + x
}

fn add<T: Add<Output = T>>(x: T, y: T) -> T {
    x + y
}

fn double_3<T>(x: T) -> T
where
    T: Add<Output = T> + Copy,
{
    x + x
}

fn add_2<T>(x: T, y: T) -> T
where
    T: Add<Output = T>,
{
    x + y
}

fn foo<A, B>(x: A, y: B) -> i32
where
    A: Display + Clone,
    B: Debug + Clone,
{
    unimplemented!()
}

fn main() {
    println!("{}", double(1));
    println!("{}", double(1.1));
    println!("{}", double_2(10));
    println!("{}", double_3(20));
    println!("{}", add(10, 2));
    println!("{}", add_2(10, 2));
}