19

I want to read a custom amount of bytes from a TcpStream, but I cannot initialize a new empty array buffer where I can define the length with a variable. It is not possible to use a vector because the TcpStream read function requires an array.

let mut buffer = [0; 1024]; // The 1024 should be a variable

When I replace the 1024 with a variable:

let length = 2000;
let mut buffer = [0; length];

I get the message:

error[E0435]: attempt to use a non-constant value in a constant
--> src/network/mod.rs:26:30
|
26 |         let mut buffer = [0; bytes];
|                              ^^^^^ non-constant used with constant

Why can't I do that?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Daniel O
  • 365
  • 1
  • 2
  • 7
  • @ljedrz It is not the same, becuase the issue from that question can be solved with a vector. In my case this is not possible, "thanks" to the TcpLibary – Daniel O Jun 30 '17 at 13:26
  • 1
    You can use a vector. You can use anything that can be dereferenced as a slice. – Boiethios Jun 30 '17 at 13:36
  • 2
    @DanielO: It is actually the same, because any contiguously allocated array (whether its size is statically known, it comes from a `Box<[T]>` or it comes from a `Vec` or whatever) can be used by slice `&[T]` and `&mut [T]`. Of course, as a newcomer you wouldn't know that immediately (not sure it's in the book), so don't worry about the question being closed, it's actually useful to have multiple "entry" points for such questions, it makes searching easier. – Matthieu M. Jun 30 '17 at 13:54

1 Answers1

14

Use a Vec with with_capacity():

use std::net::TcpStream;

fn main() {
    use std::io::Read;

    let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
    let mut v = Vec::with_capacity(128);

    let _ = stream.read(&mut v);
}

You confound array and slice. There are different in Rust: a slice is a view on the memory, previously set with an array, a Vec or whatever.

Boiethios
  • 38,438
  • 19
  • 134
  • 183
  • Not sure if things have changed because of a newer Rust version, but as of now you need to provide a type annotation for `v` (in the example) for it to compile, i.e. ```rust let mut v = Vec::with_capacity(128); // Won't compile let mut v : Vec = Vec::with_capacity(128); // WOULD compile ``` ``` – Raleigh L. Jul 12 '22 at 05:36
  • @RaleighL. I just tested it in the playground, it does compile fine. – Boiethios Jul 15 '22 at 11:47