关于Rust的所有权/生命周期的困惑[关闭]

问题描述 投票:1回答:1

以下是将两件事合并为一件的一些功能:

// It's right. move v1/v2's ownership in when call, move v's ownership back when finish.
fn combine_v(v1: Vec<i32>, v2: Vec<i32>) -> Vec<i32> {
    let v = vec![1,2,3];
    return v;
}

// It's right with lifetime statements. I can return a `&str` type var.
fn combine_s<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    let s = "123";
    return s;
}

// It's not right. 
fn combine<'a>(v1: &'a [i32], v2: &'a [i32]) -> &'a [i32] {
    let a = [1, 2, 3];
    // cannot return reference to local variable `a`
    return &a;
}

// It's not right. 
// Error: the size for values of type `[i32]` cannot be known at compilation time
fn combine_1(v1: [i32], v2: [i32]) -> [i32] {
    let a = [1,2,3];
    return a;
}

所以我有疑问:

  1. 为什么你可以返回&str类型而不是&[i32]?为什么当功能完成时&str的价值没有下降?
  2. (How)我可以编写一个接受&[i32]s的函数,并返回一个新的&[i32]吗?
  3. (如何)当编译时无法确定长度时,我可以编写一个接受[i32]s的函数,并返回一个新的[i32]吗?
  4. 为什么[i32]必须有一个长度,但&[i32]不?
rust
1个回答
1
投票

以下是您的子问题的答案:

1)为什么你可以返回&str类型而不是&[i32]?当功能结束时,为什么&str的值不会下降?

因为当你的代码编译时,它被称为'static生命周期。因此在功能完成时不会掉线。

2)如何编写一个接受&[i32]的函数,并返回一个新的&[i32]?

你的功能的签名是正确的。但是在实现中,您需要使用'static生命周期指定您的声明,或者至少以编译器将其称为'static的方式编写它。 Reference

3)当编译时无法确定长度时,如何编写接受[i32]的函数并返回新的[i32]?

要根据需要使用它们,您需要使用Box并更改您的函数签名,如下所示:Reference

fn combine_1(v1: Box<[i32]>, v2: Box<[i32]>) -> Box<[i32]>

4)为什么[i32]必须有一个长度,但是&[i32]不是?

Rust中基本上有两种形式的数组:Reference

  • [T; N]是一系列N Ts,它是大小的。
  • [T]是一个只在运行时知道的T数组,它不是Sized,只能真正被操纵为切片(&[T])

Playground

© www.soinside.com 2019 - 2024. All rights reserved.