Rust-特徵(Trait)(二)

没有Trait界限的泛型函式

上一篇范例中在宣告泛型函式中使用了where

where
    T: HasSqrt,
{

在泛型函式的宣告中如果没有where的子句引用类型参数,则该型别就没有与任何trait关联

因此只能对该泛型型别的物件做很少的事情

例如

fn f<T>(x: T) -> T {
    let c: T = x;
    let mut d = c;
    f = f2(d)
    return f
}

使用无界限的类型参数"T"只能

  • 通过值或引用将其作函式参数传递
  • 通过值或引用得从函式返回
  • 局部变数宣告或是初始化

多函式Trait

Trait也可以包含多个函式例如上一篇的范例如果要再增加绝对值abs的函式可以这样写

fn main() {
    trait HasSqrt {
        fn sq(self) -> Self;
        fn abs(self) -> Self;
    }

    impl HasSqrt for f32 {
        fn sq(self) -> Self {
            return f32::sqrt(self);
        }

        fn abs(self) -> Self {
            return f32::abs(self);
        }
    }

    impl HasSqrt for f64 {
        fn sq(self) -> Self {
            return f64::sqrt(self);
        }

        fn abs(self) -> Self {
            return f64::abs(self);
        }
    }

    fn quartic<T>(x: T) -> T
    where
        T: HasSqrt,
    {
        return x.abs.sq().sq();
    }

    let qr32 = quartic(100f32);
    let qr64 = quartic(100f64);

    println!("{} {}", qr32, qr64);
}

有时候可能只会需要平方根函式不需要绝对值函式这时候就可以抽两个Trait会更灵活

fn main() {
    trait HasSqrt {
        fn sq(self) -> Self;
    }

    trait HasAbs {
        fn abs(self) -> Self;
    }

    impl HasSqrt for f32 {
        fn sq(self) -> Self {
            return f32::sqrt(self);
        }
    }

    impl HasAbs for f32 {
        fn abs(self) -> Self {
            return f32::abs(self);
        }
    } 

    impl HasSqrt for f64 {
        fn sq(self) -> Self {
            return f64::sqrt(self);
        }
    }

    impl HasAbs for f64 {
        fn abs(self) -> Self {
            return f64::abs(self);
        }
    }

    fn quartic<T>(x: T) -> T
    where
        T: HasSqrt + HasAbs , // 这里界限宣告两个trait
    {
        return x.abs.sq().sq();
    }

    let qr32 = quartic(100f32);
    let qr64 = quartic(100f64);

    println!("{} {}", qr32, qr64);
}

"self"和"Self"傻傻分不清楚

Rust式区分大小写得

在前面的范例都使用到self和Self其中

  • 小写开头的self表示函式的值
  • 大写开头的Self标示self的型别

"self"和"Self"只能在trait或impl范围里面使用并且如果self必须是是方法的第一个参数

// 这几个范例是等效的
fn f(self) -> Self
fn f(self: Self) -> Self
fn f(self: i32) -> Self
fn f(self) -> i32
fn f(self: Self) -> i32
fn f(self: i32) -> i32

预设实作

可以针对Trait预设行为,不必要求每个型别都要实作方法,当然也可以覆盖这个预设的方法

fn main() {
    trait HasSqrt {
        fn sq(self) -> Self;
        fn helloWord(&self) -> String { // 预设实作
            return String::from("hello word");
        }
    }

    impl HasSqrt for f32 {
        fn sq(self) -> Self {
            return f32::sqrt(self);
        }
    }

    fn quartic<T>(x: T) -> T
    where
        T: HasSqrt,
    {
        println!("{}", x.helloWord());
        return x.sq().sq();
    }

    let qr32 = quartic(100f32);
}

<<:  [区块链&DAPP介绍 Day26] Dapp 实战 投票系统 - 2

>>:  Day22 Arrays and More Data Structures (Ⅱ)

DE2_115(DAY2)用niosii和switch还有NiosII console去控制板子上的led

DE2_115(DAY2)用niosii和switch还有NiosII console去控制板子上的...

Uva 10305. Ordering Tasks

      思路: 因为是看笔记教到Kahn's Algorithm,直接练习题,所以没什麽思路不...

Material UI in React [ Day 7 ] Inputs (Button Group & Floating action button) & Styles

今天会接续Button的部分做个总结。 Button Group ButtonGroup 组件可用於...

React和DOM的那些事-节点新增算法

点击进入React源码调试仓库。 本篇是详细解读React DOM操作的第二篇文章,文章所讲的内容发...

Day6 Sideproject(作品集) from 0 to 1 -定义功能

今天来介绍我们是如何从自己需要和使用者的角度来定义功能 前面有说到我们想做一个一起做sideproj...