1

Here is some functions to combine two things to one:

// 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;
}

So I have questions:

  1. Why you can return &str type but not a &[i32]? Why &str's value not dropped when function finish?

  2. (How) Can I write a function that accept &[i32]s, and return a new &[i32]?

  3. (How) Can I write a function that accept [i32]s, and return a new [i32], when the length cannot be determined at compilation time?

  4. Why [i32] must have a length, but &[i32] not?

pingze
  • 973
  • 2
  • 9
  • 18
  • 4
    so many question in one question – Stargateur Apr 03 '19 at 06:45
  • Btw: [Why is using return as the last statement in a function considered bad style?](https://stackoverflow.com/questions/27961879) – hellow Apr 03 '19 at 06:53
  • Possible duplicate of [Why can I return a reference to a local literal but not a variable?](https://stackoverflow.com/questions/50345139/why-can-i-return-a-reference-to-a-local-literal-but-not-a-variable) – hellow Apr 03 '19 at 06:53
  • @Stargateur I'll break it down into a few small problems – pingze Apr 03 '19 at 07:25

1 Answers1

1

Here are the answers to your subquestions:

1) Why you can return &str type but not a &[i32]? Why &str's value not dropped when function finish?

Because when your code compiles, it is referred as 'static lifetime. Thus it is not dropped when function finished.

2) How can I write a function that accept &[i32]s, and return a new &[i32]?

The signature of your function is correct. But in the implementation, you need to specify your declaration with 'static lifetime or at least write it in the way that compiler can refer it as 'static. Reference

3) How can I write a function that accept [i32]s, and return a new [i32], when the length cannot be determined at compilation time?

To use them as you wanted, you need to use Box and change your function signature as following: Reference

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

4) Why [i32] must have a length, but &[i32] not?

There are essentially 2 forms of arrays in Rust: Reference

  • [T; N] is an array of N Ts, it is Sized.
  • [T] is an array of T of size only known at run-time, it is NOT Sized, and can only really be manipulated as a slice (&[T]).

Playground

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
Akiner Alkan
  • 6,145
  • 3
  • 32
  • 68