►
From YouTube: Rust Linz, March 2021 - Florian Gilcher - Ownership and Borrowing from a Systems Construction PoV
Description
Rust's Ownership and Borrowing System has repercussions beyond the mere topic of memory safety. This talk approaches the topic from a different angle: interaction between components. I found this view a useful one to take when teaching Rust to programmers that enter Rust with a background of memory-safe programming languages such as Ruby, Java, or Python.
Florian on Twitter: https://twitter.com/Argorak
Rust Linz on Twitter: https://twitter.com/rustlinz
Rust Linz on the web: https://rust-linz.at
Submit your talk: https://sessionize.com/rust-linz
A
So
this
is
actually
the
first
time
I
give
a
talk
about
that
subject
and
I'm
not
sure
how
long
the
talk
is
going
to
be,
but
first
of
all
a
little
bit
about
myself.
So
hey
my
name
is
florian.
You
can
find
me
on
github
as
skate
and
on
twitter's
agruc,
which
was
basically
the
other
nickname
was
not
available.
I'm
a
rust
team
member
part
of
the
core
team
and
part
of
the
rust
foundation
board
since
a
couple
of
weeks.
A
A
But
one
thing
that
I
want
to
talk
about
is
ownership
and
borrowing
is
always
a
big
problem
for
people
to
get
their
head
around,
especially
if
you're
starting
out
with
rust
and
there's
not
a
lot
of
concepts
out
there
that
you
can
map
to
it.
So
you
need
to
learn
it
from
a
new
they're,
completely
new
concepts,
and
you
need
to
start.
They
start
cracking
them
pretty
much
immediately,
and
that
is
a
little
bit
of
a
rampant
curve
to
rust.
A
But
one
thing
that
I
always
find
interesting
is
that
they
are
often
just
seen
under
the
aspect
of
rust
as
a
memory
safe
language.
A
But
it's
not
only
that
the
and
the
goal
of
this
talk
is
to
to
take
a
little
bit
of
a
different
perspective
on
both
of
these
concepts
from
the
perspective
of
systems
construction,
because
that
is
something
that,
especially
for
newcomers,
is
much
more
relatable
and
gives
a
little
bit
of
a
of
a
of
a
view
into
the
hardships
that
they
may
find
with
it,
because
both
of
the
systems
are
actually
not
that
hard.
A
If
you're,
holding
them
right
and
the
holding
right
problem
is,
is
yeah
what
I
see.
People
run
into
a
lot,
and
that
is,
I
think,
the
more
inaccessible
part,
and
I
would
actually
just
like
to
talk
about
three
functions
in
this
talk
and
they're
all
called
the
same.
They're
all
called
right
to
file
and
they
write
a
string
to
a
file,
but
in
three
different
ways,
can
you
see
my
mouse
pointer
yeah?
Currently?
No,
yes,
yes,
we
can
see
your
mouse
pointer.
Yes,
it
works
fine.
A
I
should
have
made
it
larger,
and
the
difference
here
is
just
in
the
way
that
we're
passing
all
data.
It's
not
it's
not
even
like
the
result
type
here.
It's
just
these
two
parameters
differ
in
each
of
the
function
calls
the
first
one
is
taking
a
five
pointer
in
an
old
fashion
and
the
string
that
is
going
to
write
you
in
a
known
fashion.
A
Second,
one
is
going
to
take
the
file
in
a
known
fashion,
but
we'll
get
a
loan
out
on
the
on
the
buffer,
so
it
will
take
a
reference,
so
the
borrowing
system
gets
activated
and
the
third
one
actually
completely
borrows
here
and
the
perspective
that
I
want
to
to
discuss
these
three
functions
under
is
not
in
the
sense
of
okay.
These
are
references
in
memory,
or
this
is
like
these
are
own
memory
locations,
all
the
things
that
we
usually
do,
but
rather
from
the
perspective
on
component
boundaries.
A
I
come
to
why
component
binaries
is
useful,
expect
here,
but
if
we
talk
about
components
interacting
so
any
mid
to
large
system,
that
is
something
that
we
need
to
deal
with.
We
also
often
talking
about
the
concept
called
coupling,
so
how
strong
are
two
components
interrelated?
A
A
That
works
precisely
the
other
way
around
how
but
expresses
same
thing
so
for
this
talk
I
will
I
will
settle
on
coupling,
because
that's
the
one
that
I
like
more
in
that
low
coupling
is
good
high
coupling
is
bad,
or
at
least
harder
to
work
with.
There
are
reasons
why
you
want
to
have
high
coupling
or
why
it
might
be
useful
to
pay
the
cost
of
that
particularly
performance.
A
But
so
this
is
the.
This
is
the
thing
where
you
can
select
on
on
how
much
you,
where
you
want
to
land
in
this
equation
and
rust
may
have
a
v
complex
surface,
but
in
the
end,
boils
down
to
a
language
that
has
two
core
components,
which
is
data
and
functions
and
everything
everything
where
an
action
happens
or
data
is
getting
passes.
A
It's
usually
a
call
a
call
to
a
function
in
some
way,
so
reading
function,
signatures
and
seeing
what
we
can
read
just
out
of
the
function
signatures,
you
won't
see
a
function
body
anywhere
in
this
talk
is
actually
pretty
useful
and
being
able
to
make
to
have
some
conclusions
of
that
also
particularly
on
what
they
say
about
the
outside
world
and
the
introvert
inside
world,
and
that
particularly
means
that,
at
all
points
where
information
crosses
between
components,
you
can
see
that
at
some
point
through
some
function,
call
to
give
an
example.
A
And
the
other
one
will
we'll
call
receive
and
those
two
functions,
those
two
function.
Signatures
are
interesting
for
you.
A
There
are
components
with
a
life
cycle
relationship
so
as
an
example,
a
component
a
calls
into
a
rendering
component
b
to
render
an
image
yielding
control
fully
to
the
renderer.
So
you
have
the
maybe
your
application
and
at
some
point
it
wants
to
render
so
calls
into
a
rendering
component,
but
does
not
do
anything
until
the
rendering
is
done
and
then
gets
control
back.
A
This
is
probably
an
example
where,
where
tie
coupling
actually
makes
sense,
the
application
prepares
data
in
a
format
that
the
renderer
can
render.
So
it
knows
a
lot
about
the
data
format
that
the
renderer
needs
and
maybe
even
allows
to
write
the
renderer
to
play
around
in
some
pre-allocated
memory
spot.
A
There
are
components
without
a
lifecycle
relationship
where,
for
example,
you
have
a
database
connection
driver
which
constantly
works
in
the
background
reading
data
from
the
network,
putting
it
into
buffers
for
you
to
then
take
and
continue
working
in
it,
but
it
kind
of
has
a
life
on
its
own.
A
So
it's
spinning
there
and
you
may
submit,
for
example,
query
to
that
database
driver
and
tell
it
to
notify
you
when
it
actually,
when
it's
actually
done
through,
for
example,
an
async
runtime
or
some
other
mechanism,
but
the
database
driver
may,
for
example,
require
resources
in
it
by
itself,
for
example,
threads
and
because
that
has
a
life
on
its
own
decoding.
It
makes
sense,
because
not
knowing
all
the
details
of
what
this
thing
does
allows
you
to
change.
It
use
a
different
one
use
mysql
instead
of
postgres
and
all
these
kind
of
things.
A
So
you
it
there's
a
conscious
approach
to
not
wanting
to
know
too
much
about
what
that
thing
does
internally,
that
both
gives
that
driver
the
ability
to
change
its
own
data
structures
all
the
time
for
optimizing
it
like
as
long
as
they
are
not.
They
do
not
become
part
of
the
public
interface.
It's
no
problem
which
brings
me
to.
Why
did
I
introduce
these
three
functions?
So
imagine
you
have
a
component
that
is
just
there
for
writing
to
disk,
so
it
accepts
a
file
pointer.
This
is
where
you
want
to
write
it.
A
It
takes
a
and
it
takes
a
buffer,
and
we
have
this
function
called
right
to
file
and
with
one
component
that
calls
right
to
file
from
a
another
component
and
if
we
pass
ownership
here,
that
particularly
means
the
calling
component
is
at
after
that
function
call
immediately
freed
of
all
duties
to
manage
both
the
file
and
the
buffer.
A
The
call
component
will
take
over
this
kind
of
this.
Ownership
can
destroy
these
things
at
any
time,
can
turn
the
string
into
a
bike
buffer
or
whatever,
whatever
is
needed.
So
this
means
the
two
components.
Only
have
this
one
touch
point
and
the
first
component
gives
over
all
management
duties
to
the
other
one.
The
moment
it
is
called
so
we
have
a
clear
handover,
and
after
that
touch
point,
they
don't
need
to
know
anything
about
the
internals
they
just
negotiate
at
this
point
file
and
string.
A
The
call
component
takes
over
ownership
of
the
file
to
write
you,
so
the
first
component
does
not
care
what
happens
to
that,
and
the
call
component
can
break
that
coupling
by
copying
the
buffer
that
is
completely
feasible,
can
say.
Okay,
I
need
to
keep
this
around
for
longer.
A
For
example,
I
want
to
spin
off
a
thread
and
immediately
return
from
the
right
to
file
function
and
may
end
up
in
a
situation
where
returning
a
result
may
not
be
feasible
anymore,
but
that's
a
that's
another
thing.
I
want
to
put
that,
for
example,
I
want
to
put
that
on
the
background
thread
and
to
be
able
to
do
that,
I
copy
the
string
buffer
in
some
way.
That
is
all
possible.
A
And
the
third
one
is
coupling
even
a
little
tighter
in
that
all
responsibilities
remain
in
the
calling
component
and
especially
because
we're
passing
in
a
mutable
reference
here,
the
amount
of
stuff
that
the
this
component
needs
to
fulfill
becomes
a
larger
and
larger
immutable
pointer
in
rust
or
immutable
reference
and
rust.
Sorry
is
unique,
so
the
first
component
needs
to
make
sure
that
no
one
has
access
to
that
file
until
the
second
component
is
done
with
it.
A
If
you
are
dealing
with
a
system
that
is
larger
than
just
essentially
a
module
that
does
some
stuff
in
memory.
Ownership
is
the
preferable
handover
mechanism
between
components,
and
you
see
that
in
a
lot
of
apis
and
rust
standards
that
spawn
takes
ownership,
a
threat
gets
spawned.
It
takes
ownership
of
all
the
data
that
it
operates
on.
It's
not
working
through
borrowing.
It
particularly
bans
borrowing,
especially
when
we're
talking
about
components
that
might
run
in
parallel
with
life
cycles
on
their
own.
A
They
should
never
borrow
between
each
other,
because
the
borrowing
rules
are
static,
something
that
has
a
life
on
its
own
at
runtime
is
really
hard
to
be
described
with
a
static
with
a
static
rule
set
and
borrowing
across
components
introduces
a
lot
of
pain,
especially
if
we're
not
talking
about
passive
components-
and
this
is
where
I
see
most
of
the
problems
arising
is
not
even
like.
I
build
a
data
structure
and
I
do
some.
A
I
do
some
small
lightweight
referencing
into
it,
but
rather
people
referencing
between
components
just
naively
at
the
beginning,
but
running
into
precisely
precisely
those
problems
that
the
larger
the
project
gets
the
harder
those
rules
get
to
fulfill
while
they
should
move
away
from
using
the
borrowing
system
and
rather
focus
on
how
how
they
can
use
ownership
to
model
things,
because
ownership
is
a
great
method
to
ensure
proper
handover
between
components.
I
give
up
ownership,
and
I
give
it
to
another
component-
is
a
very,
very
common
way
to
construct
systems.
A
A
There's
a
bonus
slide
here
that
if
we
talk
about
a
a
structure
like
this,
where
we
actually
use
share
data
through
an
arc,
we
end
up
in
a
situation
where
it
is
not
easy
to
read
from
the
signature.
What
is
what
actually,
the
interaction
between
those
two
components
are
so
also
reading
function?
Signation
request
only
gets
you
that
far
at
some
point,
you
need
to
read
what
the
actual
components
are
doing.
A
As
a
final
slide
and
pointers
for
especially
beginners,
if
you
want
to
observe
this
kind
of
behavior
and
practice
with
some
easy
to
use
types,
I
can
highly
recommend
you
to
you
to
have
a
look
at
the
channel
api
with
how
senders
and
receivers
work
and
particularly
why
sender
and
receiver
are
different
types
precisely
because
of
that
and
channels
facilitate
ownership
exchange
between
components.
A
So,
if
we
imagine
the
picture
from
the
beginning
with
those
two
low
coupled
components
with
the
green
thing
in
between
the
green
thing
could
be
your
channel
where,
on
the
left
side,
you
put
things
in
and
on
the
right
side,
you
get
things
out
arc
and
rc
break
data
coupling
over
the
lifetime
that
it
remains
in
memory
because
arc
and
rc
make
sure
that
data
remains
in
memory
as
long
as
there's
parts
of
the
system
using
it
at
the
cost
of
mutation.
So
that
is
a
trade-off
here.
A
If
I
want
to,
because
immutable
data
components
reading
from
a
section
of
immutable
data
in
memory
does
not
they
don't
need
to
care
about
each
other
once
they
introduce
mutation
and
writing
again
we're
back
to
not
square
one.
But
maybe
square
three
where
they
do
need
to
find
some
way
to
negotiate.
A
There
are,
for
example,
great
types
for
a
memory,
saving
optimization
pass.
If
you
want
to
to
try
this
out,
these
are
rather
simple
constraint
types
that
will
help
you
help
you
a
lot
in
the
beginning
and
there's
types
that
are
consciously
coupled.
A
So,
for
example,
if
you
look
at
the
mutex
interface,
which
is
also
rather
accessible,
there's
a
there's,
a
type
called
mutex,
which
can
produce
a
mutex
card
which
represents
that
you
lock
the
mutex
and
that
you
currently
have
access
to
its
inner
pieces
and
the
mutex
guard
is
consciously
consciously
coupled
with
the
mutex
and
cannot
get
out
of
range
of
it.
So
to
say
so.
You
cannot
stop
referencing
the
mutex
and
but
still
keep
the
meeting
spot
around.
A
It's
the
same
goes
factor
the
iterators
of
vector
all
the
iterator
types
either
and
either
move
particularly
they
cannot
live
without
the
vector
being
around,
and
so
this
is
a
a
very
useful
method
for
for
ensuring
iterator
vitility,
because
iterators
do
not
make
sense
if
the
base,
if
the
base
structure
is
not
around-
and
this
is
what
the
borrowing
system
is
very
well
enforces.
So
if
you're
writing
these
modules
and
data
types
where
these
kinds
of
relationships
forcibly
exist,
then
it's
the
system
to
read
and
up
into
and
buy
into.
A
So.
The
conclusion
here
is
ownership
and
borrowing
have
an
interpretation
from
the
perspective
of
systems,
construction
and,
if
you
are
used
to
that,
it
might
sometimes
help
to
take
that
one
if
you
run
into
problems
with
boring
and
you
fight
with
a
lifetime
checkup
all
the
time.
A
A
With
a
component
that
is
arbitrarily
working
around
in
this
memory,
all
the
time
and
the
second
one
working
in
parallel
can
I
find
a
static
rule
that
makes
sure
references
to
the
other
components.
Memory
always
stay
valid,
it's
pretty
hard,
and
in
this
case
well,
it's
not
you
it's
the
system.
Borrowing
in
this
case
is
just
not
the
right
solution
and
the
references
are
not
the
right
solution
and
that
isn't
even
subject
to
rust.
That
is
the
same
in
a
lot
of
other
languages
as
well
as
well.
A
Just
that
just
actually
denies
you
to
writing
those
references,
but
the
fix
there
is
not
to
understand
the
borrowing
system
better,
but
to
actually
move
off
of
that
and
try
to
go
towards
owned
types
and
yeah
and
ownership
is
the
most
useful
tool
to
decouple
systems
and
the
really
really
useful
for
one
to
have,
and,
in
my
opinion,
actually
the
the
more
important
of
the
two
two
concepts
in
rust,
and
I
hope
I
give
you
a
little
bit
of
a
different
perspective
on
on
why
that
is
and
why
you
should
reach
for
it
by
default.