Rust: trait 孤儿规则

一、什么是孤儿规则
有些资料中在介绍Rust trait时,往往会带出:

Rust 有一个“孤儿规则”(orphan rule),简称OR:

“当你为某类型实现某 trait 的时候,必须要求类型或者 trait 至少有一个是在当前 crate 中定义的。你不能为第三方的类型实现第三方的 trait 。”

“在调用 trait 中定义的方法的时候,一定要记得让这个 trait 可被访问。”

不知道大家是不是都了解上面的话,在说什么? 反正不容易搞清楚。

具体地说:

(1)如果要实现外部定义的 trait 需要先将其导入作用域。
(2)不允许对外部类型实现外部 trait;
(3)可以对外部类型实现自定义的 trait;
(4)可以对自定义类型上实现外部 trait。

外部是指不是由自己,而是由外部定义的,包括标准库。

case1

let mut f = std::fs::File::open("C:/Users/rustr/Desktop/foo.txt").ok().expect("Couldn’t open foo.txt");
let buf = b"whatever"; //  buf: &[u8; 8]
let result = f.write(buf);
# result.unwrap();

报错=>

error[E0599]: no method named `write` found for type `std::fs::File` in the current scope
  --> src\main.rs:51:20
   |
51 |     let result = f.write(buf);
   |                    ^^^^^
   |
   = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
   |
1  | use std::io::Write;

因为违反了第一条“如果要实现外部定义的 trait 需要先将其导入作用域”。

加上下面的就好了:

 use std::io::Write

case2:

use std::ops::Add;
struct mydata(i32);
impl Add<i32> for mydata{
    type Output =i32;
    fn add (self,other:i32)->Self::Output{
        (self.0) + other
    }
}
fn main(){
      assert_eq!(mydata(5)+6,11);
 }

为什么不违反OR规则?
mydata的类型是本地的;虽然Add trait是标准库带的。=》“可以对自定义类型上实现外部 trait。”

case3: 如果加上一个新的类型

 impl Add<i32> for Option<mydata>{
     type Output =i32;
     fn add (self,other:i32)->Self::Output{
         (self.0) + other
     }
}

为什么编译会违反OR?

因为Option< mydata >不是本地定义的类型。即=>“不允许对外部类型实现外部 trait;”

二、一些特例:Box、Fn、FnMut、FnOnce、Sized;与 #【fundamental】

impl Add<i32> for Box<mydata>{
    type Output =i32;
    fn add (self,other:i32)->Self::Output{
        (self.0) + other
    }
}

根据“不允许对外部类型实现外部 trait:,上面的类型Box < mydata > 也应编译通不过。但实际上,是可以的。

Rust对Box< T >开了绿灯,这个 绿灯,是rust内部在类型定义时,在Box类型时,用了特别的标识

#[fundamental]

三、为什么rust要设OR ? 有什么苦衷?

特补充。。。。。。

OR 是为了加快编译?或在指向上更加清晰?

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值