►
From YouTube: Rust Cologne: Fn traits
Description
https://media.ccc.de/v/rustcologne.2018.09.fn-traits
This talk explains how you can use the Fn* traits to properly accept functions and closures as function parameters,
and gives an overview of which closures implement which traits.
Florob
A
Okay,
yeah
second
targets
the
night
I'm
going
to
talk
the
FN
family
about
the
event
family
of
trades,
short
interaction
concerning
me,
because
I
didn't
do
that.
Yet
my
name
is
Florian
or
Florrick,
around
hackerspaces
and
the
internet
and
stuff
I'm.
Actually,
the
second
professional
rest
developer
in
the
room.
Apparently
I
do
embedded
audio
hardware
with
template,
Linux
and
all
the
sort
of
management,
software
and
sources
rust.
They
actual
like
signal
processing
are
FPGAs,
but
we
do
most
of
the
management
stuff
web
interface,
backends
and
everything
else
in
rows,
so,
okay
event
rates.
A
So
what
RFM
traits
event
rates
is
a
family
of
traits
as
a
set
defined
in
the
standard
library,
and
their
purpose
is
basically
defining
an
interface
with
things
that
are
in
one
way
or
the
other
callable.
So
if
you
want
your
object
to
be
callable
on
you
definite
rate
for
it,
that's
a
bit
of
a
lie,
but
we'll
get
to
that
and
also
like
obviously,
closures
and
functions,
implement
the
event
rates
automatically.
A
Let's,
let's
assume
that
right
so
right
for
sorry
something
that
post
comments
are
talked
about.
What
is
the
most
plausible
argument
for
this
message
like?
Should
it
be
taken
by
by
value,
or
should
this
be
a
reverence
of
mutable
reference?
And
actually,
let's
just
do
that
by
relevance.
You
are
a
bit
experience
or
at
Pascal
song
should
have
an
idea.
Artists
who
do
things
like
taking
distract
itself
by
by
value
as
a
self
is
the
most
possible
option
here.
A
Immutable
reference:
there
was
one
vote
for
a
reference,
isn't
mutable
reference
to
people
and
nothing,
not
even
a
method.
That's
like
gee,
most
votes,
well
kind
of
disagree,
so
the
constraints
I
talked
about
just
half
a
minute
ago.
Is
we
want
this
to
be
callable
on
an
instance
of
this
right,
so
it
needs
to
actually
be
a
method.
You
cannot
have
instant
and
then
call
a
free
function
of
the
type
on
the
instance
so
actually
need
this
to
have
some
self
parameter
in
order
to
be
method
and
the
most
possible.
A
A
Okay,
so
yeah.
So
let's
say
that's
Sam
some
photos.
Let's
make
this
slightly
more
useful,
slightly
different.
So
whatever
we
attach
some
data
set
struck
right.
So
we
cannot
just
say
hell
arrest
with
hello
to
someone
it
specifics
like
give
a
string
to
the
struct
that
we
can
include
there
and
read
it
so
doesn't
make
any
difference.
No,
not
really.
As
long
as
we
just
use
the
value
inside
the
struct
by
reference
itself,
it's
sufficient!
A
If
we
also
have
our
struct
by
reference
right,
because
we
can
get
to
as
long
as
we
don't
move
it
out
and
we
tied
it
or
whatever
having
read-only
access
to
your
instructors,
fine,
so
that
also
works
okay,
another
step.
So
let's
say
we
want
to
have
an
object
and
whenever
we
call
it
guesses.
The
next
item
in
the
Fibonacci
sequence
right.
So
if
you're
not
a
word
from
not
shoot
sequence,
basically
starting
with
two
values:
1
and
1,
adding
the
map
and
basically
shifting
through
them,
so
that
you
get
it
a
certain
sequence.
A
A
Ok,
yes,
so
that's
that's
exactly
what
I'd
say
to
you
like.
We
need
to
mutate
the
data
in
this,
so
we
sort
of
it
not
only
makes
most
sense
to
take
it
out,
but
we
said
I
have
to
take
it
at
that.
The
other
option
would
be
to
take
a
cell.
That
also
works,
and
this
also
is
implementations.
We
can
write
for
this.
The
program
was
called
once
it's
sorted
that
you
only
ever
get
the
first
value
of
the
Fibonacci
sequence.
A
A
A
Okay,
so
yeah
we're
pretty
much
anomalous.
That
by
value
makes
most
sense
and
the
reason
is
pretty
simply
that
we're
actually
moving
the
vector
out
of
our
struct
right.
So
if
we
just
took
the
reference
we
couldn't
do
that
it
wouldn't
be
allowed
to
use
data
that
the
struct
contains
and
just
move
it
somewhere
else.
We
need
to
own
the
struct,
so
we
can
move
to
the
data
out
of
it.
So
in
this
case
we
could
just
implement
call
once
so
simply
enough.
A
So
what
we've
seen
now
a
little
East
I'm
trying
to
convince
you
of
that
is
for
calling
object.
There
is
no
real
one-size-fits-all
solution,
but
we
can
certainly
define
some
some
traits
that
would
work
and
we'll
just
call
them
similar
to
the
functions
we've
had
before,
like
we
have
the
trade
F
and
once
that
trade
gets
an
Associated
type
and
that
type
is
the
return
type
of
the
function.
A
So
to
speak
and
like
coming
back
to
simple
when
you
seeing
people
said
in
Pascal
stock,
that
only
makes
sense
isn't
associated
type
because
being
generic
over
the
output
would
mean
that
the
function
can
return
different
things,
but
obviously
it
only
really
has
one
return
type.
So
this
makes
sense
in
the
search
it
to
type
on
yeah.
Then
that
means
call
once
takes
easy
structure
or
whatever
you
have
by
value
and
gives
you
something
of
the
output
type.
Is
a
trade
and
then
going
down
the
chain.
A
We've
seen
that
if
something
is
callable
immutably
so
but
hanging,
we
took
a
reference
to
it.
Then
you
can
also
call
it
once
so.
There's
a
dependency
between
these
trades
and
I.
Don't
think,
that's
color
that
you
introduced
yet
you
can
have
traits
that
are
super
traits
of
another
one.
So
if
you
implement
one
the
other
one,
that
also
has
to
be
implemented,
and
this
is
basically
what's
that
code
on
the
same
like
if
you
ferment
F,
and
what
for
something?
It
also
needs
to
support
a
fan
once
and
in
the
same
fashion.
A
A
Yeah,
why
I
repeat
it
just.
B
A
So
yeah,
that's
that's
one
factor.
This
is
certainly
annoying
and
also
like
I
feel,
like
people
have
commented
about
this
being
annoying
before
I
actually
started
this
talk,
but
it
also
like,
as
the
first
sentences
we
sorted
by
the
slides
before
that-
maybe
determined
that
there
is
no
real,
one-size-fits-all
solution,
so
that
might
be
a
necessary
evil
falling
out
from
Russell
Sipe
system
because,
like
if
you
have
a
immutable
reference
to
something,
it
would
be
hard
to
implement
a
trait
for
it.
A
That
also
enables
you
to
call
it
mutable
or
you
would
require
that
everything
you
ever
can
call
you
need
to
have
ownership
of,
which
is
also
not
with
an
option.
So
now
the
extra
problem
with
this
and
maybe
I've
not
been
paying
attention,
but
none
of
this
function
could
take
arguments.
That
is
a
bit
boring.
Is
it
not
and
yeah?
That's
what
we're
basically
missing
and
we
can
have
a
return
type
and
it
can
be
anything
we
want
for
a
specific
function,
but
we
cannot
have
any
arguments
and
it's.
A
The
problem
with
that
is
rest
doesn't
really
have
message
with
very
etic
parameter,
counts
or
very
addict
generics
for
that
matter,
so
we
can't
really
define
a
trade
that
would
actually
have
that
property
to
you,
like
was
the
argument
number
that
we'd
want
for
a
function,
because
that's
not
really
something
rest.
Isis
can
do
right
now.
So,
but
still
these
exists,
and
this
is
what
the
actual
trades
looked
like
and
they
look
a
bit
complicated.
A
So
you
just
have
one
generic
argument
called
arcs
and
then
the
actual
functions
are
a
bit
special
like
extern,
or
the
string
behind
extern
always
specifies
an
ABI.
If
you
leave
it
off,
it's
just
CZ
standard
api,
but
in
this
case
it's
rust
call
and
horse
call
is
a
special
ABI
and
like
I'll
claim
it's
mostly
just
there
for
this
very
specific
case.
That
basically
makes
this
magic
arcs
argument.
So
any
number
of
parameters
that
you
passed
or
an
actual
function
call
and.
A
A
So
this
is
the
first
example
like
closures,
as
you
might
have
seen
before,
usually
start
with.
Like
two
pipes,
the
arguments
would
go
in
between
those
and
then
the
actual
code
block,
either
as
a
block
or
as
a
single
statement.
In
this
case
it's
a
single
straightening,
dessert
print
line
and
it
basically
the
sugars
internally
to
pretty
much
the
same
stream
that
we
saw
the
very
first
slide.
It
creates
a
struct
with
an
anonymous
name,
type
name
in
this
case.
It's
just
the
type
of
the
closure
and
it
gets
trade
implementations.
A
So
you
can-
and
usually
you
would
call
that,
like
it's
done
here
in
fine
form,
that's
the
purpose
of
first
traits
from
it
chooses
the
most
appropriate
of
the
straight
and
basically
calls
its
call
function
and
then
just
to
demonstrate
that
the
traits
are
actually
implemented.
I
put
those
calls
in
lines
5
to
7
in
there.
So-
and
you
already
see
that
something
is
iffy
about
those
arguments
because
all
of
them
take
an
empty
Chapel
right,
it's
like
zero
I'm,
a
double
and
that's
where
a
couple
of
all
the
arguments
would
go.
A
A
Ok
great,
so
let's
go
to
our
more
useful
creatures,
so
we
would
want
to
have
a
name
inside
set
right,
so
we
first
define
a
variable
called
name
and
we
put
Cologne
in
there
as
a
string,
and
then
we
let
our
closure
close
over
that
variable
right
included
in
the
closure,
so
also
in
the
object,
reference,
the
variable
and
then
printing.
That's
part
of
our
print
alone,
and
that
should
be
roughly
the
same
as
we
saw
in
a
seconds
right
right.
Does
anyone
think
it's
not
for
whatever
reason.
A
Okay,
so
let's,
let's,
let's
try
something
different,
so
let's
not
just
create
the
closure
and
call
it
immediately.
Let's
create
that
culture
inside
a
function.
We
turn
it
from
that
function
and
then
call
it
okay.
So
we
now
have
a
greeter
function
and
it
takes
a
name.
It
gives
us
back
a
closure
that
will
greet
someone
right.
A
A
It's
just
basically
looking
like
a
function,
call
and
says
this
implements
the
event
rate
and
then
just
empty
parentheses
for
saying
a
function
that
has
no
arguments,
particularly
so,
okay,
and
if
we
try
to
compile
that
and
give
it
a
string
as
an
argument,
it
says:
well
the
closure
that
you're
creating
in
that
function
may
actually
outlive
the
function
and
well
yes,
it
does.
We
returned
it
from
the
function.
A
Of
course
it
is,
but
it
borrows
name
so
the
parameters
that
we
gave
that
function
right,
which
will
only
be
live
up
to
the
end
of
greeter,
because
then
it
gets
destroyed
but
wait.
Why
is
it
borrowing
name
specifically,
and
the
reason
for
that
is
that
the
actually
sugaring
of
this
looks
much
more
like
this.
As
I
said,
we
can't
actually
implement
the
event
rate
for
things
but
like
just
as
pseudocode
they
seem.
A
So,
judging
from
the
usage
of
a
certain
variable
inside
a
closure,
it
decides
whether
to
capture
it
by
reference
or
by
mutable
reference
or
actually
move
it
inside
the
closure
and
since
Britain
only
uses
its
arguments
after
the
first
point
by
reference
just
for
printing
it
and
doesn't
actually
consume
it
or
anything
like
that
or
modify
it.
It
decides
well,
the
reference
should
be
plenty,
so
obviously
that
doesn't
work
for
specific
cases
like
this,
where
you
would
want
to
return
the
closure
from
the
function.
A
So
there
is
a
little
let's
say
trick
to
avoid
this,
which
is
basically
using
a
mobile
closure
so
to
create
a
move
closer.
All
you
do
is
write,
move
in
front
of
the
closure
and
that
what
that
will
do
is
any
variable
referenced
inside
that
closure
will
actually
be
moved
inside
the
closure.
So
now,
instead
of
looking
at
okay
name,
is
only
used
by
reference.
So
I'll
only
take
a
reference.
A
Little
got
sure
about
this
interesting
enough.
Move
closures
can
still
contain
references
and
the
way
that
you
would
get
that
is.
If
you
have
arrival
that
itself
contains
the
reference
and
use
that
variable
inside
the
closure.
It
will
capture
a
variable
containing
a
reference,
thereby
still
capturing
your
reference
and
if
you
actually
want
to
move
the
closure
far
somewhere
else
or
actually
just
outside
of
a
function
that
would
still
try
to
trip
you
up.
A
Basically
the
same
thing:
we
have
two
variables:
first,
declaring
them
as
free
and
then
creating
a
move
closure
right
so
both
of
those
variables
since
we're
using
them
inside
the
closure
will
be
moved
into
the
closure,
and
then
we
can
change
them,
mutate
them
inside
the
closure.
It's
basically
pretty
much
the
same
code
as
we
had
before,
actually
lowing
you
but
simpler,
even
and
when
calling
it
will
always
return.
The
next
element
of
the
Fibonacci
sequence.
A
The
difference
is
that
this
time
around,
if
you
try
to
call
fib
call
so
giving
it
a
immutable
reference
yet
reference,
the
compiler
will
tell
you
well.
Fn
is
not
implemented
for
that
closure
and
that's
a
bit
of
the
magic
that
coaches
get
like
the
compiler
will
look
at
the
way
the
closure
actually
uses
its
captures
and
only
implement
those
trades
that
are
actually
applicable.
So
in
this
case,
we
you
taking
our
captures
and
therefore
the
FN
trait
cannot
be
implemented
anymore
because
we
need
at
least
immutable
borrow.
A
Fn
wants
to
still
there,
though
so
and
last
but
not
least,
or
a
nonce
version,
looks
pretty
simple.
We
just
have
a
variable
that
contains
a
vector
and
then
our
non
so
closure
that
returns.
That
variable
is
enough.
You
will
notice
that
this
time,
I
did
not
use
move
as
a
specific
reason,
for
that
is
that
this
funk
is.
This
closure
actually
uses
the
variable
in
a
way
that
it
needs
in
in
a
way
so
that
it
needs
to
move
it
so,
every
time
it
can
actually
directly
see
that
this
is
a
move.
A
It
will
infer
that.
Okay,
if
I
move
this
variable,
I'll
also
have
to
move
myself.
Sorry,
so
in
this
case
only
F
and
once
it's
implemented
because
of
the
way
I
wrote
this
code
having
these
like
normal
call
in
line
for,
of
course,
you
still
can't
call
a
call
once
because
it's
been
moved,
that's
unfortunate,
but
basically
its
various
implemented.
You
can
still
call
by
that
any
questions
so
far.
A
That's
exactly
is
the
same
as
in
function,
so
the
last
expression
in
the
closure
is
the
return
value.
Otherwise
this
would
have
to
say
return
and
yes,
that
would
also
work.
Maybe
you
would
need
braces
and
I'm,
not
actually
sure,
probably
not
anything
else,
okay,
cool
so
yeah
as
promised.
What
if
we
actually
like,
don't
want
to
create
something
that
you
call
but
take
in
something
that
you
call
right
the
other
way
around.
A
So,
as
I've
said
before,
we
can't
use
the
event
rates
directly
as
straight
balance,
unfortunately,
because,
as
I
said,
they
are
unstable,
but
still
important.
So
of
course
rust
has
resolution
frizzes
and
that's
basically
just
as
there's
syntax
sugar
and
arguably
it's
not
lysosome.
If
we
would
have
to
use
so
stress
directly.
It
just
looks
like
the
three
bullet
points
you
see
at
the
bottom.
A
You
basically
write
it
like
in
normal
function,
signature
just
using
the
trade
name
instead
of
but
as
a
joke
as
a
fan
or
a
fan
function
name,
and
you
can
use
that
concert
as
a
trade
pad
or
as
an
argument
to
the
impose
trade
construct
or
to
box
things
up.
President
read
so
yeah:
let's,
let's
look
at
a
simple
example
of
this,
so
let's
say
we
have
some
abstraction.
This
is
a
pretty
artificial
example,
but
I
think.
Hopefully
it's
simply
not
so
we
have
an
instruction
type
struct.
A
It
contains
one
element
of
any
type,
so
it's
generic
over
a
type
T
and
it
contains
one
element
of
that
type
right
and
we
want
to
implement
map
for
it
so
map,
basically
taking
the
element
inside
the
abstraction,
passing
it
through
function
and
then
returning
the
the
result
of
that
function,
wrapped
again
in
that
abstraction,
so
pretty
similar
to
what
an
option
would
be
if
there
was
no
number
Li
and
I
guess
so.
The
way
we
do
that
is,
we
have
our
map
function
and
it
has
two
generic
arguments.
A
A
So,
okay,
obvious
question:
what
happens
if
we
need
to
call
that
function
twice,
because,
for
example,
we
have
an
abstraction
over
two
elements
and
we
want
to
bullet
map
both
of
them
again
fairly
artificial
examples.
Well,
not
much,
basically
the
exact
same
thing
as
before,
just
that
the
trait
bound
we
have
to
new.
So
now
is
FN
much
again.
A
Fn
matt
is
also
implemented
for
everything,
that's
FN,
so
we
can
do
that.
We
take
every
closure
that
would
be
possible
to
take
in
this
case,
so
everything
we
can't
take
implements
only
FN
one,
so
can
only
be
called
once
and
since
we
need
to
call
it
twice
or
that
say
this
was
mapping
aware
vector
any
amount
of
time.
A
Okay,
yeah
other
way
around,
so
we've
pretty
much
seen
that
before,
but
still
T
to
make
the
point
again,
we
can
also
return
closures,
so
not
taking
them
in
essen
arguments,
but
returning
them
from
a
function,
and
this
is
a
pretty
simple
one.
It
just
gives
us
the
closure
callable
that
returns
five
always
and
yeah
I
use
infiltrate
in
this
case
and
saying
that
this
returns,
something
that
is
callable
by
reference
and
returns
to
you,
64
and
not
possibly.
This
is
pretty
much
the
other
way
around
from
what
we
had
before.
A
It's
not
F
and
once
as
the
most
general
case,
but
it's
FN,
and
the
reason
that,
in
this
case,
I'd
consider
event
to
be
more
general.
Is
that
in
return
position
giving
this
to
someone
who
is
going
to
call
it,
and
you
want
to
allow
the
caller
to
call
it
no
matter
if
he
has
a
reference
to
it
or
owns
it
or
has
mutable
reference
to
it.