rust


How to swap elements of array?


I want to swap elements of slice data using library function, but it doesn't work because of multiple borrowing:
mem::swap(&mut data[i], &mut data[j]); //error
It could be done manually, as usual:
let temp = data[i];
data[i] = data[j];
data[j] = temp;
but I don't think using this code every time is great. Is there any other solution to use library swap for slices normally?
There's a swap method on slices: data.swap(i, j).
The original code doesn't work because the language requires that &muts do not alias, that is, if a piece of data is accessible via an &mut, then there must be no other way to use that data. In general, for successive indexes data[i], data[j], the compiler cannot guarantee that i and j are different. If they are the same then the indexing is referring to the same memory and so &mut data[i] and &mut data[j] would be two pointers to the same data: illegal!
.swap uses a bit of unsafe code internally, being sure to handle the i == j case correctly, avoiding aliasing &mut pointers. That said, it doesn't have to use unsafe, it is only to ensure this "primitive" operation has high-performance (and I could definitely imagine future language/library improvements that reduce the need for unsafe here by making the require invariants easier to express), e.g. the following is a safe implementation:
use std::cmp::Ordering;
use std::mem;
fn swap<T>(x: &mut [T], i: usize, j: usize) {
let (lo, hi) = match i.cmp(&j) {
// no swapping necessary
Ordering::Equal => return
// get the smallest and largest of the two indices
Ordering::Less => (i, j),
Ordering::Greater => (j, i)
};
let (init, tail) = x.split_at_mut(hi);
mem::swap(&mut init[lo], &mut tail[0]);
}
The key here is split_at_mut which separates the slice into two disjoint halves (this is done using unsafe internally, but Rust's standard library is built on unsafe: the language provides "primitive" features and the libraries build the rest on top of them).

Related Links

Safely traversing a directed acyclic graph
Borrowing reference in structure
Is only using references the most idiomatic/efficient for “big” structures?
How to write a method that adds `self` as a mutable trait reference to a collection?
How do I modify a value after matching on it?
Drop a Rust void pointer stored in an FFI
Iterate two vectors and the rest of the larger one
How do I implement Clone/Copy for an enum that contains a String?
Modeling embedded hardware in Rust and how to have multiple mutable references cleanly?
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]

Categories

HOME
office365
livecode
concurrency
stacktrace.js
dafny
website
qooxdoo
ui-automation
graphql-js
reportviewer
circleci
powermock
dhcp
django-rq
synthesis
vmware-workstation
pygobject
exec-maven-plugin
unity-container
android-permissions
neo4j.rb
quantitative-finance
restier
opentext
fusetools
password-generator
hdmi
hevc
running-object-table
uilocalnotification
bonita
unmarshalling
nic
objectmapper
mapnik
nsmutablearray
wampsharp
ms-media-foundation
counting
winrm
cmis
des
keyboard-layout
nsuserdefaults
installanywhere
cartopy
telephonymanager
llvm-ir
aurelia-http-client
widestring
spring-restcontroller
right-click
jacoco-maven-plugin
klee
type-inference
adblock
autorelease
nonlinear-functions
comm
amazon-elastic-beanstalk
spring.net
skip-lists
android-sharing
winmerge
nivo-slider
dex
kendo-treeview
okio
openquery
livereload
coovachilli
ajax4jsf
boost-proto
google-maps-api-2
srv-record
bjam
blockquote
artisan
fuseesb
mathematical-expressions
xml-signature
libgcc
full-text-indexing
android-2.3-gingerbread
distributed-r
windows-messages
redpitaya
preorder
cpu-time
armv6
yii-booster
ember-table
eager-loading
oembed
contextswitchdeadlock
red-system
struts2-json-plugin
nsmutablestring
stretch
sfinae
cakeyframeanimation
type-safety
microblogging
botnet
nosetests
digiflow
mygeneration
pinax
sscli
processors
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