Introduction: Vectors Are Simple, Until You Need to Join Them
\nImagine: you are writing a Rust program that processes data. You get two Vec<i32> and want to combine them into one. It seems simple, right? But anyone who has asked this question on Stack Overflow (and there are thousands of them) knows: in Rust, there are at least 5 ways to do this, and half of them are mistakes that either won't compile or will kill all performance.
In this article, we will break down the popular question “What is the best way to concatenate vectors in Rust?” and turn it into a practical guide. You will learn how to concatenate vectors correctly, what pitfalls await beginners, and how to write efficient Rust code. Let's go!
\n\nWhy is Concatenating Vectors in Rust Not Such a Trivial Task?
\nUnlike Python or JavaScript, where you can simply write list1 + list2, Rust requires you to explicitly specify what you want to do with memory. A vector in Rust is not just a list, but a structure that owns data on the heap. Operations with it can lead to:
- \n
- Reallocations (copying the entire buffer). \n
- Loss of ownership (move semantics). \n
- Unnecessary cloning (if the data is large). \n
Therefore, the choice of method depends on the context: whether you need to keep the original vectors, what data type is inside, and whether speed is important.
\n\nTop 5 Mistakes When Concatenating Vectors in Rust
\nLet's go through the most common pitfalls that beginners (and not only) step on.
\n\nMistake #1: Using + for Vec (won't compile)
\nThe most intuitive, but incorrect attempt:
\nlet v1 = vec![1, 2, 3];\nlet v2 = vec![4, 5, 6];\nlet v3 = v1 + v2; // Error! cannot add `Vec<{integer}>` to `Vec<{integer}>`\nThe + operator is overloaded only for strings and numbers, but not for vectors. Rust does not allow adding collections directly.
Mistake #2: Forgetting about move and losing data
\nMany use append and are surprised that the first vector becomes empty:
let mut v1 = vec![1, 2, 3];\nlet mut v2 = vec![4, 5, 6];\nv1.append(&mut v2);\nprintln!("{:?}", v2); // Empty! v2 is now empty.\nappend moves elements from the second vector into the first, leaving v2 empty. This is efficient, but not always expected.
Mistake #3: Naively cloning everything
\nWhen you need to keep both original vectors, beginners often write:
\nlet v1 = vec![1, 2, 3];\nlet v2 = vec![4, 5, 6];\nlet mut v3 = v1.clone();\nv3.extend(v2.clone()); // Two clones!\nFor large vectors with String or complex structures, this kills performance. It's better to use references or chain.
Mistake #4: Ignoring capacity with extend
\nSimple extend can cause multiple reallocations:
let mut v1 = vec![1, 2, 3];\nlet v2 = vec![4, 5, 6];\nv1.extend(v2); // If v1's capacity is small, there will be a reallocation.\nIf you know the final size, it's better to allocate memory in advance: v1.reserve(v2.len()).
Mistake #5: Confusing extend and append
\nextend takes an iterator and can clone elements (if you pass &vec). append moves elements without cloning. The choice is not obvious until you read the documentation.
Best Ways to Concatenate Vectors in Rust (with Examples)
\nNow that we know the enemy, let's look at the correct approaches. Each is good for its own scenario.
\n\nMethod 1: extend — universal and clear
\nThe most common method. Adds ele