rust


How to idiomatically copy a slice?


In Go, copying slices is standard-fare and looks like this:
# It will figure out the details to match slice sizes
dst = copy(dst[n:], src[:m])
In Rust, I couldn't find a similar method as replacement. Something I came up with looks like this:
fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
let mut c = 0;
for (&mut d, &s) in dst.iter_mut().zip(src.iter()) {
d = s;
c += 1;
}
c
}
Unfortunately, I get this compile-error that I am unable to solve:
error[E0384]: re-assignment of immutable variable `d`
--> src/main.rs:4:9
|
3 | for (&mut d, &s) in dst.iter_mut().zip(src.iter()) {
| - first assignment to `d`
4 | d = s;
| ^^^^^ re-assignment of immutable variable
How can I set d? Is there a better way to copy a slice?
Yes, use the method clone_from_slice(), it is generic over any element type that implements Clone.
fn main() {
let mut x = vec![0; 8];
let y = [1, 2, 3];
x[..3].clone_from_slice(&y);
println!("{:?}", x);
// Output:
// [1, 2, 3, 0, 0, 0, 0, 0]
}
The destination x is either a &mut [T] slice, or anything that derefs to that, like a mutable Vec<T> vector. You need to slice the destination and source so that their lengths match.
As of Rust 1.9, you can also use copy_from_slice(). This works the same way but uses the Copy trait instead of Clone, and is a direct wrapper of memcpy. The compiler can optimize clone_from_slice to be equivalent to copy_from_slice when applicable, but it can still be useful.
Warning copy_memory has been deprecated since Rust 1.6.0. Check out bluss' answer for a stable solution.
I'd probably use copy_memory, which has almost the same signature as what you want:
use std::slice::bytes;
use std::cmp;
fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
let len = cmp::min(src.len(), dst.len());
bytes::copy_memory(&mut dst[..len], &src[..len]);
len
}
fn main() {
let mut a = [1u8, 2, 3];
let mut b = [9u8];
//copy_slice(&mut a[], &b[]);
copy_slice(&mut b[], &a[]);
println!("{:?}, {:?}", a, b);
}
Note that this is not a generic solution. In Rust, slices can be of any type, including ones that are not easily-copyable! Your question, and this answer, only deal with slices of u8.
This code works, even though I am not sure if it the best way to do it.
fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
let mut c = 0;
for (d, s) in dst.iter_mut().zip(src.iter()) {
*d = *s;
c += 1;
}
c
}
Apparently not specifying access permissions explicitly did the trick. However, I am still confused about this and my mental model doesn't yet cover what's truly going on there.
My solutions are mostly trial and error when it comes to these things, and I'd rather like to truly understand instead.
Another variant would be
fn copy_slice(dst: &mut [u8], src: &[u8]) -> usize {
dst.iter_mut().zip(src).map(|(x, y)| *x = *y).count()
}
Note that you have to use count in this case, since len would use the ExactSizeIterator shortcut and thus never call next, resulting in a no-op.

Related Links

Indexing a String
Importing mio::tcp::TcpStream but get std::net::tcp::TcpStream
It is possible to always have Cargo show warnings?
Copy files to the target directory after build
Is it ok to return in main?
Why is this trait/implementation incompatible - bound lifetime vs concrete lifetime
Cannot move out of `req` because it is borrowed
remove duplicates from vector of custom struct
error with % operator inside closure
How can I open a file with the standard text editor?
How to use multiple variables in routes with Nickel?
sdl2-sys won't compile - could not exec the linker: No such file or directory
Cannot borrow as mutable more than once at a time in one code - but can in another very similar
Forcing a move for an implemented `Copy` type
When do I need to specify explicit lifetimes in Rust?
cannot borrow `self.x` as immutable because `*self` is also borrowed as mutable

Categories

HOME
jboss
ionic2
yaml
yii
redmine
twitter-fabric
mathematical-optimization
qooxdoo
openflow
drag-and-drop
capistrano
javafx-8
cisco
sharepoint-online
swarm
azure-graph-api
hystrix
spring-security-oauth2
fasm
fbloginview
documentum
bundler
closures
vertica
playframework-2.0
cocos2d-android
robolectric
pickle
tfsbuild
libgit2
web-analytics
mime-types
pdf.js
unordered-multimap
iwebbrowser2
audit
autodesk-model-derivative
progid
windows2012
python-2.x
john-the-ripper
epplus
caesar-cipher
shapeless
listjs
winrm
grails-2.5
landscape
redgate
cordys-opentext
mv
django-smart-selects
rdp
sbjson
task-parallel-library
flowchart
system-on-chip
destroy
rightnow-crm
entropy
mobile-angular-ui
dtd
predicates
msxml
sidewaffle
haraka
pyaudio
vaadin4spring
accessibilityservice
servicestack-bsd
python-cffi
google-maps-api-2
openshift-cartridge
apache-commons-digester
android-handler
google-gdk
cache-manifest
unidata
ocmockito
fat32
juttle
adwords-apiv201402
window-resize
dmake
relationships
siena
android-2.3-gingerbread
senchatouch-2.4
meteor-collections
code39
particle-swarm
hyphen
xsd2code
libxml-js
chartfx
semantic-merge
cgrectmake
voice-recording
first-class
uitextfielddelegate
trialware
uploading
multidrop-bus
django-apps
qtextbrowser
kext
azure-acs
odac
source-code-protection
subtext
objectinstantiation
code-camp

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App