网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > Rust >

rust学习二十.8、RUST特质的限定,实为对类型的限

时间:2025-03-31 17:58

人气:

作者:admin

标签:

导读:有的时候,可能希望使用的特质已经实现了其它特质(看后面可以知道,实际是要求相关类型实现了其它特质)。 RUST支持为特质(trait)指定限定的特质。 例如我们定义特质A,之后定义了...

有的时候,可能希望使用的特质已经实现了其它特质(看后面可以知道,实际是要求相关类型实现了其它特质)。

RUST支持为特质(trait)指定限定的特质。

例如我们定义特质A,之后定义了类型T,这个时候还希望T已经实现了特质TC

在rust中就是这个语法:

trait tx:t1

trait tx:t1+t2..+tn

根据相关数据的例子和说明,需要特别注意,具体的实现都是依赖于类型,而不是特质。

一、示例1

use std::fmt;

struct Point {
    x: i32,
    y: i32,
}
trait Copy{
    fn copy(&self) -> Self;
}
trait OutlinePrint: fmt::Display+Copy{
    fn outline_print(&self) {
        let output = self.to_string();
        let len = output.len();
        println!("{}", "*".repeat(len + 4));
        println!("*{}*", " ".repeat(len + 2));
        println!("* {output} *");
        println!("*{}*", " ".repeat(len + 2));
        println!("{}", "*".repeat(len + 4));
    }
}

impl OutlinePrint for Point {}
impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}
impl Copy for Point {
    fn copy(&self) -> Self {
            Point { x: self.x, y: self.y }
    }
}

fn main() {
    let p = Point { x: 10, y: 20 };
    p.outline_print();
    let c=p.copy();
    c.outline_print();
}

在本例中Point必须实现特质Copy和Display和OutlinePrint,注意OutlinePrint的定义:

trait OutlinePrint: fmt::Display+Copy

多个特质之间用+号连接。

输出如下:

 

二、示例2-在方法中使用特质有关方法

把以上的例子稍微修改下:

use std::fmt;

struct Point {
    x: i32,
    y: i32,
}
trait Copyable {
    fn copy(&self) -> Self;
}
trait OutlinePrint: fmt::Display + Copyable +Sized{
    fn outline_print(&self) {
        // 先创建副本
        let copied = self.copy();
        // 然后将副本转换为字符串
        let output = copied.to_string();
        let len = output.len();
        println!("{}", "*".repeat(len + 4));
        println!("*{}*", " ".repeat(len + 2));
        println!("* {} *", output);
        println!("*{}*", " ".repeat(len + 2));
        println!("{}", "*".repeat(len + 4));
    }
}

impl OutlinePrint for Point {}
impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}
impl Copyable for Point {
    fn copy(&self) -> Self {
            Point { x: self.x, y: self.y }
    }
}

fn main() {
    let p = Point { x: 10, y: 20 };
    p.outline_print();
}

本例中,首先为OutlinePrint增加一个限定Sized,其次方法outline_print是先copy再to_string.

如果OutlinePrint不添加一个Sized,那么会提示语句 let copied=self.copy()报错:doesn't have a size known at compile-time

rustc的给出的建议是:fn outline_print(&self) where Self: Sized  ,即为方法outline_print的参数添加限定(这是我们习惯的方式)

为什么Point不需要实现Sized?这是因为Point的大小是确定的,其次编译器会为此类类型隐式实现

输出略。

三、示例3-如果不使用特质的限定

由于可以为方法的参数进行限定,我们很容易想到其实可以只对参数限定即可。

为了节约篇幅,这里只把核心的内容贴出:

trait OutlinePrint{
    fn outline_print(&self)
    where Self: fmt::Display + Copyable+Sized
     {
        // 先创建副本
        let copied = self.copy();
        // 然后将副本转换为字符串
        let output = copied.to_string();
        let len = output.len();
        println!("{}", "*".repeat(len + 4));
        println!("*{}*", " ".repeat(len + 2));
        println!("* {} *", output);
        println!("*{}*", " ".repeat(len + 2));
        println!("{}", "*".repeat(len + 4));
    }
}

输出:

四、小结

这种定义方式个人认为不是很符合一般思维方式,这是因为明明是对类型的限制,但是这种限制确写在特质上。

例如在java等语言中,就没有这种方式。

个人更加倾向于采用示例3的方式,尤其是在接触多了类似JAVA之类的OOP语言后。

 

当然rust这种定义方式也有优点:如果相关特质方法的参数都是这种要求,那么写在特质上,的确会少打一些字。

所以,rust程序员可以根据需要来决定限定方式,某种程度上rust为我们提供了方便性和灵活性。

 

本文来自博客园,作者:正在战斗中,转载请注明原文链接:https://www.cnblogs.com/lzfhope/p/18802354

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信