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

Should I borrow or copy my small data types?
Using pointer casting to change the “type” of data in memory [duplicate]
Export function only to module test?
Take slice of certain length known at compile time
Is it possible to deactivate file locking in cargo?
“does not live long enough” error in same function
What ways exist to create containers of several types? [duplicate]
How can I optimize reading a UTF-8 string from a file with a known offset and size?
Create vector of objects implementing a trait in Rust
Using loop variable from “..” loop causes type conversion?
What is RFC 401's coerce_inner useful for?
Rust Borrow checker only complains about borrowing as mutable multiple times when a function that returns a reference with the same lifetime assigned
How can I remove `let _ : () = …`?
Does if-let with a pair short-circuit?
Rust borrow lasts beyond the scope it's in?
How can I include an arbitrary set of Protobuf-built files without knowing their names?

Categories

HOME
nam
automapper
dotnetnuke
paypal-ipn
applescript
braintree
adobe
yql
facebook-android-sdk
gprs
cisco
polymer-2.x
clickable-image
hystrix
documentum
fullcalendar-scheduler
multi-step
nose
parceler
home
spring-ldap
bsd
maven-surefire-plugin
conda
candlestick-chart
jstree
acrobat
macromedia
laravel-4.2
ninject
sparkle
amazon-iam
jsonresult
winsock
devtools
transform
cloudera-quickstart-vm
linq.js
python-jira
newtons-method
oauth2-playground
web-inspector
virtual-memory
expandablelistview
dredd
supertest
hibernate-ogm
webvtt
mura
freshdesk
ptvs
nrf51
allegro
nclam
ftp-client
between
piping
groovyfx
odp.net-managed
verisign
as3-api
management-studio-express
ioexception
supercomputers
artisan
unidata
mod-auth-openidc
google-hangouts
tabris
communicate
treeline
two.js
property-injection
vlab
apache-shindig
sql-view
postgres-xc
xs
donut-chart
contextswitchdeadlock
red-system
user-forums
clearinterval
image-scanner
autosize
wcf-callbacks
space-partitioning
directshow.net
simile
activestate
jquery-effects
webclient.uploaddata

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