rust--as_ref和borrow的区别

// as_ref和Borrow的区别 ?

// as_ref 是转引用函数, 将具有所有权对象转换成引用对象,
// 不改变被转换对象的基础上产生一个引用对象.

// as_ref 并不是所有类型都默认支持, 很多时候都需要自己去声明.
// as_ref 是AsRef trait 的公共接口方法.
// 只有那些实现了 as_ref 公共接口方法的类型才能使用as_ref.
// 目前: Option, Box, Result 这三种类型默认提供支持as_ref.

// as_ref 和 Borrow 的区别是:
// 基础数据类型引用:
//     Borrow 可以直接在 int, &str, String, vec, [], struct, enum 这种类型上直接指定&来引用.
//     as_ref 则不行, 它需要声明泛型T: AsRef<int>, T: AsRef<str>, T: AsRef<struct name> 来支持.
// 嵌套数据类型引用: Some(&int) , Box(&int) ,
//     Borrow 必须在定义结构时声明 Some<&int> , Box<&int> 才是引用.
//     as_ref 则直接可以在这些嵌套结构上使用as_ref.
// 引用的引用
//     Borrow 引用的引用的表现形式是:   &str -> &&str
//     as_ref 引用的引用的表现形式是:   &str -> &str


fn borrow_example() {
    let s = 1;
    let x = &s;                                                                // 直接引用
    println!("s:{}; x: {}", s, x);
}


fn borrow_nest_example() {

    fn hello(x: Option<&i32>) -> Option<&i32> {                                          // 指定Some<&i32>
        match x {
            Some(_item) => x,
            None => None
        }
    }

    let s = 1234;
    let z = hello(Some(&s));                                                   // 传入之前要先把引用声明好.
    println!("s: {};  z: {:?}", s, z);
}


#[allow(dead_code)]
#[allow(unused_variables)]
fn borrow_reference_to_reference() {
    let a: &str = "str";
    let b: &&str = &a;
}


fn as_ref_example() {

    // as_ref 在这种场景的使用上不如 borrow,
    // 这是因为这种写法要求把所有权转移进来.
    // 又不能把&str 返回回去, 因为生命周期会冲突.
    // 所以as_ref不建议在这种场景下使用.

    fn hello<T: AsRef<str>>(x: T) {
        let xx = x.as_ref();
        println!("xx: {}", xx);
    }
    let s = String::from("hello");
    hello(s);
}


fn as_ref_nest_example() {

    // as_ref 非常适合这种场景, 简单快捷.

    fn hello(x: Option<i32>) -> Option<i32> {
        x.as_ref();                                                            // Option<i32>  to  Option<&i32> 很方便后续代码的编写.
        x
    }

    let s = 1234;
    let z = hello(Some(s));
    println!("s: {}; z: {:?}", s, z);
}


fn as_ref_reference_to_reference() {
    #[allow(dead_code)]
    #[allow(unused_variables)]
    fn hello<T: AsRef<str>>(x: T) {
        let y: &str = x.as_ref();
        let z: &str = y.as_ref();                   // 引用上再引用, 永远只有一层引用.
    }

    let s = "hello";
    hello(s);
}


fn main() {
    borrow_example();
    borrow_nest_example();
    borrow_reference_to_reference();
    as_ref_example();
    as_ref_nest_example();
    as_ref_reference_to_reference();
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.as (1)从派生类转换成基类,(upcasts)向上转换,即:子类向父类转换. 定义一个父类People c...
    柚子皮肤阅读 1,889评论 0 0
  • 1.as的使用场合 1.从派生类转换为基类,向上转类型(upcasting) 2.消除二义性,数值类型转换 3.s...
    蓝色的风阅读 5,143评论 2 6
  • 快速原型制造 传统零件设计受制造工艺影响不能做的很合理——新的CAD设计 RPW发展 3D打印 医学应用
    defineaset阅读 250评论 0 0
  • 我厌恶我周边的人 在我看来 他们 愚昧,无知 热爱吹嘘,假模假样 我对他们的唯一感觉 恶心 但 我对他们露出 羞涩...
    姜伯衡阅读 185评论 0 1
  • 生活不易,难为自己,实在可惜
    OO7344阅读 112评论 0 0