美文网首页
rust--as_ref和borrow的区别

rust--as_ref和borrow的区别

作者: 极光火狐狸 | 来源:发表于2018-09-15 08:40 被阅读81次
// 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();
}

相关文章

网友评论

      本文标题:rust--as_ref和borrow的区别

      本文链接:https://www.haomeiwen.com/subject/uhdzgftx.html