【问题标题】:Borrowing from an owned box inside a tuple in Rust从 Rust 元组中的自有盒子借用
【发布时间】:2014-04-18 16:50:48
【问题描述】:

主要目标是访问元组内的拥有框,例如下面代码中来自(String, i32) 的字符串。

我的第一个意图是使用let 绑定从拥有的盒子中借用。借用适用于非元组情况 (1),但不适用于涉及元组时 (2)。

我的意图是否错误,如果是,是否有另一种惯用的方式来访问字符串?

示例代码:

fn main() {
    // 1. Normal borrowing
    let s: String = "blub".to_string();
    let sr: &str = &s; // this works

    // 2. Borrowing from a tuple
    let st = ("blub".to_string(), 1);
    let (st_r, i): (&str, i32) = st; // error: mismatched types:

    println!( "{} {} {} {}", s, sr, st_r, i);
}

编译错误是:

error: mismatched types:
 expected `(&str, i32)`,
    found `(collections::string::String, _)`

【问题讨论】:

    标签: rust borrowing


    【解决方案1】:

    ref 关键字用于通过引用进行绑定。

    let (ref st_r, i) = st;
    

    【讨论】:

    • 请注意,当你这样做时,你会得到st_r: &~str,而不是st_r: &str。这就是为什么无论如何都需要as_slice() 的原因。这可以很容易地检查:println!("{}", st_r as int); 导致error: non-scalar cast: &~str as int
    • as_slice() 电话绝对是答案的重要组成部分。在我的代码中,我最终使用了等效的 if let (ref st_r,i)=st; let st_r = st_r.as_slice()。在匹配方法中再提到两次int 感觉有点多余。
    【解决方案2】:

    我认为最直接的方法是匹配:

    let st = (~"blub", 1i);
    let (st_r, i) = match st {
        (ref s, i) => (s.as_slice(), i)
    };
    println!("{} {}", st_r, i);
    

    请注意,我使用 ref ss.as_slice() 而不是 s&*s 有两个原因。首先,由于~str 类型的当前特殊状态,不允许使用&*s。似乎在 DST 换地时有可能。其次,我使用了ref s,因为否则第一个元组组件被移动到s,并且根本不可能从match主体内部返回对它的引用——当match时它将被销毁结束。

    i 没有这样的问题,因为int 是隐式可复制的。

    【讨论】:

    • 您可能应该为 Rust 1.0 及更高版本更新此问题。
    【解决方案3】:

    如果您只关心元组的单个值,您还可以使用数字访问器(.0.1 等)。这些可以应用引用运算符&

    let st = ("blub".to_string(), 1);
    let st_r = &st.0;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      相关资源
      最近更新 更多