►
From YouTube: From OOP to GO
Description
No description was provided for this meeting.
If this is YOUR meeting, an easy way to fix this is to add a description to your video, wherever mtngs.io found it (probably YouTube).
A
Let
me
start
by
introducing
myself
I'm
a
software
engineer
at
work
out
we're
working
on
building
a
debugger
for
production.
I
come
from
a
background
of
low-level
programming
in
c
and
Linux,
iot
environments
and
I,
really
love
learning
new
technologies,
new
programming
languages
and
especially
how
they
work
behind
the
scenes
and
their
internals.
A
Now
workout
supports
six
different
languages
and
for
each
of
those
languages
we
have
a
different
product
in
that
language,
so
we
I
find
myself
translating
a
lot
of
code.
One
of
my
first
tasks
here
was
to
translate
a
section
of
code
from
java
to
go.
This
talk
is
based
off
of
that
experience.
The
mistakes
I
made
and
the
tips
and
tricks
I
learned
along
the
way.
A
Now,
let's
start
by
asking
ourselves
the
question,
what
is
oop
well
I
know
some
people
think
it
is
a
variation
of
these
four
principles,
but
these
are
the
commonly
regarded
principles
of
oop.
So
the
first
is
abstraction,
which
means
that
we
don't
need
to
know
how
something
works
in
order
to
use
it.
Basically,
it's
representing
complexity
through
simplicity,
encapsulation
is
differentiating
between
things
that
should
be
publicly
accessible
to
all
or
private
or
accessible
to
only
certain
objects.
In
your
code,
pomorphism
is
using
different
types
through
the
same
interface
and
inheritance.
A
A
So
the
big
question
is:
go
oop
now,
I
know
some
people
say
definite.
Yes,
some
people
say
definite
no,
and
these
are
the
three
things
that
I
like
to
consider
when
facing
this
question.
First
of
all,
go
has
types
but
no
type
hierarchy.
A
Now
these
types
can
also
have
methods
on
them,
but
even
the
simplest
types
can
have
methods
so
types
like
int
or
string
which
come
built
in
in
the
language.
You
can
extend
them
with
new
methods
and,
lastly,
interfaces
are
implemented
implicitly,
so
interfaces
do
exist
in
go.
They
allow
for
polymorphism
an
abstraction
of
some
sort,
but
they
are
implemented
implicitly.
So
the
class
or
the
stress
that
is
implementing
this
interface
doesn't
even
need
to
know
if
it
exists
of
its
existence.
A
This
makes
interfaces
much
more
lightweight
than
interfaces
in
other
languages
or
P
languages
such
as
Java
or
c-sharp,
so
they're
also
much
more
common
in
code.
You'll
find
many
more
interfaces
in
go
rather
than
in
other
op
languages.
So
considering
these
three,
we
do
see
that
go
satisfies
most
of
the
oop
principles
I
mentioned,
but
a
big
principle
that
go
doesn't
satisfy
is
inheritance
and
I.
Don't
just
want
to
tell
you
this
I
want
to
show
you
why
inheritance
doesn't
work
and
go
foreign.
A
Just
as
I
did
we're
going
to
translate
that
logging
library
from
java
to
go
and
see
where
common
mistakes
and
pitfalls
can
happen,
so
our
login
library
has
two
main
requirements.
First
of
all,
we
need
to
support
multiple
log
levels
and
we're
going
to
have
a
function
for
each
of
those
log
levels.
Secondly,
we're
going
to
want
user-defined,
login
Targets.
A
Having
a
write
method
was
just
prints,
tested
out
and
I'm,
creating
a
debug
method
which
calls
that
write
method.
Obviously,
we
need
to
add
four
more
those
four
other
log
level
functions,
but
just
for
the
sake
of
fitting
this,
all
on
one
page,
I
decided
to
keep
those
out,
but
they
look
exactly
like
debug
with
different
log
levels.
A
Awesome.
So,
in
order
to
use
this
logger,
we
can
just
create
a
new
logger
instance
called
the
debug
method
and
we're
printing
to
stdm
exactly
what
we
wanted.
Now.
If
the
user
wanted
to
log
to
say
a
file,
he
could
just
extend
the
existing
logger.
So
in
Java
we
have
the
extends
keyword
which
just
inherits
from
the
extended
class.
So
in
this
case
logger
and
sorry
bylogger
extends
longer
so
file.
Logger
is
inheriting
all
of
bloggers,
attributes
and
methods.
A
So
we
are
going
to
override
the
right
method,
and
so,
instead
of
writing
to
STV
out
we're
going
to
write
to
a
file.
Now,
when
we
put
that
all
together,
we
can
create
a
new
file,
logger
instance
instead
of
a
new
logger
instance,
and
when
we
call
the
debug
method
on
that,
we're
actually
logging
to
a
file
great.
A
But
now
we
can
go
so
we're
really
going
to
translate
this.
But
before
we
can
actually
start
translating,
we
need
to
know
a
concept
called
embedded
structs
now.
This
is
a
very
simple
example:
we
have
our
ABC
struct.
This
ABC
struct
has
one
field
I
of
type
int
and
one
method
Foo
once
again,
very
simple.
A
Now,
in
order
to
embed
the
ABC
struct
in
another
struct,
we
just
need
to
write
the
name
of
the
struct
in
the
struct.
We're
embedding
it
so
in
this
case
we're
embedding
ABC
in
the
my
type
struct.
Now
what
this
causes
as
that
ABC's
fields
and
methods
are
promoted
to
my
type.
So
my
type
now
has
access
and
can
use
these
fields
and
methods
exactly
like
ABC
does
so
we
have
access
to
the
I
field.
A
A
So
just
as
we
did
here,
I've
embedded
the
logger
struct
in
the
file
logger
struct.
In
addition
to
embedding
the
lottery
script,
I've
also
added
a
file
name
field
just
so
that
we
can
keep
the
file
name
and
maybe
pass
it
once
we
initialize
the
file
logger.
So
once
again,
as
you
probably
know,
Ingo,
we
don't
have
Decor
decorators
or
annotations
like
in
Java,
so
we
don't
have
that
override
annotation,
so
we'll
just
create
the
right
method
without
that
annotation
and
write
to
a
file
instead
of
to
SD
yet
great.
A
A
So,
first
of
all,
creating
a
method
in
go
is
not
very
different
than
just
creating
a
function
and
passing
the
receiver
as
the
first
parameter.
So
in
this
case
we
have
the
debug
method
and
logger
is
the
receiver,
the
receipt
type,
but
it's
exactly
the
same
as
creating
a
debug
function
and
just
passing
the
logger
type
as
the
first
parameter
now.
A
Another
thing
we
need
to
know
about
go
is
that
embedding
a
struct
is
not
really
like
inheritance,
it's
more
like
creating
a
nice
wrapper
that
go
does
for
us,
so
embedding
a
struct
is
kind
of
like
just
adding
a
field
to
the
struct
or
embedding
in
so
in
this
case,
creating
embedding
the
logar
struct
in
file.
Logger
is
not
very
different
than
creating
a
logger
field
on
file
logger
and
then
what
about
those
promoted,
attributes
and
functions?
A
Well,
the
debug
method
that
now
exists
on
the
file
logger
because
we
embedded
logger
is
not
more
than
just
a
wrapper.
So
in
this
case
we
can
just
wrap
the
debug
function,
the
debug
method
on
file
locker
and
inside
it
just
call
the
debug
method
on
logger.
So
what's
really
happening
when
we
embed
a
struct
in
another
struct
is
go,
is
creating
all
these
wrappers
behind
the
scenes
and
doing
all
this
without
us,
even
knowing
which
can
be
really
neat
at
times,
but
can
also
be
kind
of
buggy
in
other
times
like
this
one.
A
A
Then
we
reach
this
function
right,
the
debug
method
and
since
it's
a
wrapper
that
go
created
for
us
what's
actually
happening
is
we're
calling
the
debug
method
on
the
logger,
not
the
file
logger,
so
a
retail
debug
method
on
the
logger
right.
This
is
the
same
function.
So
at
this
point
we
have
no
semblance
to
the
file
logger.
It's
long
forgotten
longer,
doesn't
know
it
was
part
of
a
file
logger
once
it
doesn't
know
where
it
was
called
from
and
we've
just
lost
the
file
logger
context.
A
A
In
addition,
we
need
to
stop
translating
code
and
Concepts,
so
I
learned
Java
after
I
already
knew.
C
sharp
and
translating
Concepts
from
c-sharp
to
Java
really
helped
me
get
into
the
language
faster
and
not
have
to
learn
everything
from
scratch.
But
when
I
do
this
with
go,
I
often
find
myself
having
these
really
hard
to
detect
bugs
because
they're,
just
not
these
languages,
aren't
meant
to
go
hand
in
hand.
They're
not
meant
to
be
translated
from
one
to
another.
A
So
we
need
to
rethink
how
we
do
things
when
we
do
them
and
go
now.
I
will
say
that
for
basic
concepts
like
translating
just
a
struck
to
a
class,
it
will
work.
So
keep
those
Basics,
but
when
we
get
to
more
advanced
things,
we
do
want
to
think
them
through
and
make
sure
we're
doing
the
correct
thing.
And
last
but
not
least,
we
need
to
Google
everything.
A
So
this
is
true
for
all
programming
languages,
but
I
found
this
especially
true
for
go
no
matter
how
long
I
code
and
go
I
still
find
that
Google
searching
a
very,
very
simple
term
might
end
up
with
a
very
different
solution,
which
is
much
better
much
simpler
works
way
better
than
my
original
solution,
so
really
Google
everything,
even
if
you
think
you
know
you
might
not
know
and
now
back
to
our
logger.
Let's
talk
about
the
Practical
logger
solution.
A
Additionally,
we're
going
to
use
interfaces
in
all
the
solutions,
interfaces
as
I
said:
they're
common,
they're
lightweight.
Why
not
use
them
now?
I
will
say
that
we
want
to
not
abuse
interfaces,
so
use
them
wisely,
make
sure
you're
not
creating
an
interface
for
just
one
concrete
type.
But
in
this
case
we
have
the
STD
out
Target
and
the
file
Target,
and
this
is
a
great
example
of
when
we
can
use
an
interface
right.
A
Let's
go
back
to
polymorphism
we're
talking
about
representing
using
different
types
through
the
same
interface,
and
we
want
to
return
to
our
goal,
because
our
original
design
just
wasn't
good
for
go
so
once
again,
we're
talking
about
functions
for
each
log
level
and
user
defined
login
targets
so,
like
I,
said
a
really
good
place
for
an
interface.
Is
our
logging
Target
so
we're
going
to
create
a
login,
Target
interface
with
that
write
method
in
it
one
method,
very
simple,
very
straightforward.
A
A
lot
of
go
interfaces
are
just
one
method
and
that's
how
they
should
be
very
lightweight.
Now
we're
going
to
create
a
global
variable
called
Target
and
have
that
be
of
type
logging.
The
target,
in
addition,
we're
going
to
create
a
debug
function
right
and
go.
We
don't
need
all
fun
all
functions
to
be
methods,
part
of
a
struct.
You
can
just
have
functions
like
that,
so
we're
just
going
to
have
a
debug
function
that
calls
the
right
method
on
our
Global
Target
variable
then
we'll
create
our
standard.
A
Login
Target
we'll
create
that
a
simple
struct,
no
Fields,
with
what
method,
the
right
method,
which
prints
test
DB
out,
then
we'll
create
a
file.
Logging
Target
once
again,
very
simple
struct.
We
might
have
a
few
fields
in
it.
I
didn't
write
them
here,
but
we
might
not
want
to
use
a
file
name
field
now.
I
did
want
to
create
a
Constructor
for
our
file,
logging
Target
and
go.
A
We
don't
have
Constructors,
but
I
did
create
a
new
file
on
target
which
I
expect
the
user
to
use
when
they
create
a
file
login
Target
instance
that
will
just
save
our
file
name
and
let
us
have
more
control
over
how
that
file.
Login
Target
is
created
and
then
create
the
right
method
which
just
writes
to
a
file.
So
now,
both
by
log
and
Target
and
standard
login
Target,
are
implementing
the
logging
Target
interface
great.
Now,
the
only
piece
missing
is
to
be
able
to
set
the
login
Target.
A
So
I've
created
a
set,
long
Target
function
which
accepts
a
new
Target
as
a
parameter,
and
that
will
just
switch
the
new
old
Target
to
the
new.
If
I
wanted
to
do
anything
else
like
validate
the
new
Target
or
something
like
that,
I
could
do
it
in
this
function.
So
having
the
user
call
this
function
instead
of
just
set.
The
target
directly
allows
me
more
control
over
that
which
is
nice.
A
So,
let's
use
this
we'll
create
a
standard.
Login
Target
instance
set
that
to
be
our
login
Target
call
the
debug
function
and
we're
logging
to
St
yet
great
the
same
way.
We
can
create
a
new
file
login
Target
instance
call
the
set
log
Target
function
with
that
file,
Target
so
set
that
to
their
logging,
Target
call
the
debug
function
and
we're
logging
to
a
file.
So
this
is
a
great
solution.
It
works,
but,
as
I
said,
we
should
Google
everything
in
this
case.
One
Google
search
away
is
this
interface.
A
This
is
the
I
o
dot
writer
interface,
the
writer
interface
and
the
I
o
package.
The
I
o
package
is
a
standard
package
in
go.
It
comes
with
a
standard
Library,
literally
every
go
binary
out.
There
has
this
interface
already
in
it,
so
this
interface
is
very,
very
similar
to
our
login
Target
enter
this
right.
They
both
have
the
right
method
and
they
accept
different
parameters
and
they
return
different
values
but
they're,
basically
the
same
right
point
and
the
end
is
the
same.
A
So
let's
just
do
one
small
change
and
have
our
Target
go
from
the
logging
Target
type
to
the
io.writer
type,
and
now
we
can
use
OS
dot,
stdo
os.stv
out
right,
the
STD
out
variable
in
or
const
in
types
of
arrival
in
the
OS
package.
It
already
implements
the
io.writer
interface,
so
we
don't
have
to
create
our
own
standard
logging
targets
drug
to
implement
the
write
method.
We
already
have
something
in
the
standard
library
that
implements
that
for
us
and
our
implementation
has
become
so
much
smaller,
so
much
simpler.
A
We
don't
have
to
write
all
this
extra
code,
which
is
just
wrappers
for
functions
and
things
that
already
exist.
So
we
once
again
we
can
set
OS
dot
STD
out
to
be
our
logging,
Target
call
the
debug
method
and
we're
printing
to
STD
out
now,
like
os.stvl
for
files,
we
have
the
OS
dot
create
function.
The
OS
dot,
create
function,
creates
a
file
and
returns
some
sort
of
file
struct
to
us.
A
Now,
since
the
file
struct
already
implements
the
io.writer
interface,
we
can
use
that
to
be
our
logging,
Target
call
the
debug
function
and
we'll
log
into
a
file,
so
that
simple
change
really
made
a
big
difference.
Now,
because
of
that
change,
we
support
logging
to
buffers
to
sockets
to
files
and
even
to
hashes.
If
someone
wanted
to
now.
In
fact,
the
last
time
I
checked,
the
io.writer
interface
was
implemented.
A
351
types
in
the
standard
go
Library
alone,
so
right,
they're,
not
all
useful
for
our
case
for
a
logger,
but
still
that
small
changed
that
small
change
made
it
so
much
some
product
to
use
our
code
and
users
don't
need
to
wrap
existing
behaviors
and
new
functions
and
Implement
a
new
interface
just
to
use
our
code.
So
once
again,
Google
search
everything
okay.
A
But
what
if
we
wanted
to
log
to
multiple
targets
or
choose
which
Target
to
use
based
on
a
context
right?
What?
If
we
wanted
to
log
both
to
a
file
and
to
a
studio
or
say
we
wanted
one
function
to
lock
to
a
file
and
one
function
to
log
to
sddl?
What
I'm
getting
at
is
that
our
logger
needs
to
be
an
object.
This
will
allow
for
more
versatile
use
of
our
object.
A
So
we
need
to
go
back
to
embedded
strengths,
but
this
time
we're
going
to
add
a
little
twist
instead
of
embedding
a
struct
in
another
struct
we're
going
to
embed
an
interface
in
a
struct.
Now
this
is
very
similar
and,
let's
see
how
that
works.
Well,
we're
going
to
create
a
very
simple
interface
call
it
my
interface
with
a
one
method,
the
flu
method.
A
Now,
because
we
want
a
concrete
type
that
implements
this
interface,
we're
going
to
create
my
implementation,
very
simple,
empty
struct
that
implements
my
interface
great
now,
just
as
we
embedded
a
struct
in
another
struct.
Embedding
an
interface
in
a
struct
is
just
writing.
That
interface
is
tight.
The
name
of
the
type
inside
the
struct,
so
just
as
we
see
here
in
this
case
we're
embedding
my
interface
in
my
screen
now
we'll
create
an
instance
of
my
implementation.
We
need
to
do
this.
A
We
need
to
have
a
concrete
instance
of
a
concrete
type
in
order
to
embed
an
interface
and
struct,
and
then,
when
we
create
an
instance
of
my
struct
we're
going
to
pass
that
implementation
as
the
interface
so
putting
that
all
together.
What
that
means
is
that
calling
the
foo
method
on
M
and
calling
the
foo
method
on
I
leads
to
the
exact
same
behavior?
A
A
So
let's
use
that
in
our
solution.
Well
we're
going
to
create
a
logar
struct
we're
not
going
to
go
back
to
using
our
logging
Target
interface,
because
we
already
have
that
io.writer
interface.
So
we're
going
to
embed
the
io.writer
interface
in
our
locker
struct
foreign,
then
once
again
just
for
more
control
over
how
our
logger
is
created,
we're
going
to
create
a
Constructor
for
our
logger
right.
The
new
logger
function
and
it'll
accept
a
writer
and
we're
going
to
return
a
new
logger
with
that
writer
as
the
interface.
A
So
we're
also
going
to
create
the
debug
method,
and
this
debug
method
will
call
the
right
method
on
the
log.
A
A
So
the
first
thing
I
wondered
was
what,
if
I
don't
pass
and
implementation
of
the
writer
interface
like
right
here,
I've
just
created
a
lot
of
stuff
I
haven't
passed
it
an
implementation
of
the
io.writer
interface
and
I,
call
the
debug
method,
but
then
I
got
a
runtime
error,
so
it
was
a
panic.
It
was
invalid
memory
address
or
nil
pointer
to
reference
and
I
got
a
very
long,
stat
Trace,
but
eventually
the
line
that
was
problematic
was
the
call
to
the
right
method
on
Blogger
now.
A
The
reason
for
this
is
that
calling
the
right
method
on
the
logger
is
actually
trying
to
call
the
right
method
on
the
io.writer
implementation
that
we
passed
to
logger.
But
since
we
didn't
pass
such
an
implementation,
the
Iowa
DOT
writer
is
null
or
nil
because
we're
in
go
and
so
we're
trying
to
call
a
method
on
a
nil
object
which
will
obviously
lead
to
a
nail
pointer.
A
But
that's
okay,
because
I
thought
to
myself.
Well,
what
if
I
just
create
my
own
implementation
of
the
right
method
right
so
I
had
logger,
implement
the
io.letter
interface
itself,
while
also
embedding
the
Iota
writer
interface
in
the
struct,
and
the
right
method
was
very,
very
straightforward.
Just
call
print
right
print
to
SDF
and
I
put
that
all
together
and
I
created
a
logger
instance
and
I
called
the
debug
method
and
it
printed
tests
DB
out,
so
we're
not
dealing
with
that
nil
pointer
reference
Panic
that
we
had
earlier.
So
that's
great.
A
This
was
what
I
expected
to
happen
right,
so
maybe
I
actually
could
create
a
default
implementation
for
a
logger,
but
then
I
tried
it
with
a
file
and
I
created
a
file
and
I
created
a
new
logger
around
that
file
and
I
called
the
debug
method,
but
I'm
still
printing
to
stdf.
So
my
conclusion
was
that
I
was
just
overriding
any
implementation
of
the
write
method
by
the
interfacing
by
the
interface
we're
embedding.
So
this
wasn't
very
helpful
but
say:
I
did
still
want
to
create
that
default
implementation.
What
could
I
do
well?
A
First
of
all,
I
could
create
I,
since
I
have
control
over
how
our
logger
is
created,
because
I
created
that
Constructor
for
our
logger
right,
the
new
logger
function.
Well,
I
can
just
have
the
user
pass
Nimble
as
the
writer,
and
if
the
user
passes
nil,
as
the
writer
I
know,
I
need
to
use
the
default
implementation
in
the
default
implementation
is
to
write
to
a
studio.
A
So
in
this
case,
so
in
this
case,
if
we
call
the
new
logger
function
with
nil,
we
would
just
be
logging
to
STD
out
and
if
we
call
the
new
logger
function
with
something
that
wasn't
now,
we
would
be
logging
to
that
Target.
A
A
Well,
in
this
case,
we
could
just
create
the
new
logger
function
and
have
it
return
a
logger
with
the
default
being
os.stv
as
the
writer
and
then,
if
the
user
wanted
something
else
that
wasn't
the
default
writer,
we
could
just
create
a
set
Target
method
on
our
logger
struct
and
change
the
writer
to
be
the
writer
the
user
requested.
A
So
putting
that
all
together,
we
can
very
very
easily
just
create
a
logger
and
have
it
default
to
STD
out
and
change
it
up
and
log
to
somewhere
else.
If
we
wanted
to
so,
both
are
valid.
Solutions
depends
on
what
the
user
expects
and
who
your
user
is
going
to
be
and
how
well
you
document
it
now.
This
isn't
the
first
time
I've.
A
Given
this
talk
and
the
last
time
Bill
Kennedy
was
in
the
crowd,
which
was
amazing,
and
he
came
up
to
me
and
we
started
talking
about
embedding
an
interface
and
a
struct,
and
a
big
question
was
is
embedding
an
interface
in
a
struct
and
anti-pattern.
Is
that
something
that
shows
me
that
my
code
isn't
the
best
it
could
be?
And
while
we
were
having
our
conversation,
I
realized
that
this
isn't
the
question
I
should
be
asking.
A
The
question
we
should
be
asking
is:
is
this
the
simplest
way
to
do
this,
because
not
all
cases
of
embedding
an
interface
in
a
struct
are
good
cases
to
embed
an
interfaces,
but
not
all
cases
where
we
embed
an
interface
and
struct
are
also
bad,
so
this
can
be
useful,
but
we
should
be
mindful
of
where
we
use
this,
and
let's
take
our
logging
example
and
see
if
the
way
we
embedded
interface
is
good
or
bad
by
asking
ourselves.
Is
this
the
simplest
way
to
do
this?
A
So,
first
of
all,
let's
go
back
a
little
like
we
realized
how
embedded
structs
work.
The
same
thing
happens
with
embedded
interfaces
right.
So
when
we
embed
the
iodar
radar
interface
and
logger
struct,
it's
no
different
than
just
creating
a
writer
field
of
type
io.writer
in
the
log
restruct
and
then
creating
a
wrapper
function,
a
wrapper
method,
the
right
method,
which
calls
the
writer
Fields
write,
method
right.
So
now
that
we
know
this
well,
first
of
all,
we
can
do
this
ourselves
right.
We
can
just
have
the
writer
field
on
the
logger
struct.
A
We
don't
really
need
that
wrapper
function,
because
we're
only
calling
the
right
method
a
few
times
and
there's
no
reason
not
to
just
call
the
right
method
on
the
writer
field
directly.
So
in
this
case,
I
really
think
that
What's
Happening
Here
is
the
simplest
way
to
do
this,
like
when
I
consider
if
I
want
to
create
a
field
or
if
I
want
to
embed
an
interface.
I'd
probably
opt
for
the
field
because
in
this
case
we're
just
using
one
function
from
that
interface.
A
So
it's
not
creating
a
lot
of
wrapper
functions
if
we
wanted
to
create
those
wrapper
functions
and
also
we're
using
that
interface
only
internally
in
our
code,
so
there's
no
real
reason
to
just
go
for
the
interface
for
the
embedding.
The
interface
solution.
Also
embedding
an
interface
might
be
quite
confusing.
Not
everyone
knows
what
happens
when
the
interface
and
also
when
someone
calls
the
right
method
on
the
logger.
They
might
expect
the
implementation
to
just
be
of
the
logger
and
not
to
change
depending
on
how
the
logger
was
created,
so
putting
that
all
together.
A
So,
let's
take
a
step
back
for
a
second.
What
changed
in
our
mindset
to
allow
for
our
new
code
to
work
right.
We
showed
two
solutions.
We
even
tweaked
our
last
solution
a
bit
and
all
of
these
Solutions
actually
worked,
except
for,
but
in
contrast
to
our
first
solution,
which
had
a
really
hard
to
detect
bug.
Well,
first
of
all,
we're
not
extending
our
logger
right.
A
A
So
changing
our
mindset,
not
thinking
about
inheritance,
but
this
is
more
of
taking
the
composition
side
of
the
inheritance
versus
composition,
kind
of
debate,
so
taking
composition.
That's
the
way!
Go
works,
that's
a
good
way!
Go
intense!
You
to
work
with
it,
we're
kind
of
using
dependency,
ejection
right,
we're
injecting
the
outer
arter
interface
when
we
initialize
that
logger.
A
So
all
of
these
are
things
you
should
consider
when
you're
coding
and
go
and
once
again,
I
said
this
multiple
times,
but
translating
code
from
any
language
to
go
really
might
cause
some
problems,
because
we're
just
talking
about
different
concepts
and
things
that
might
look
very
similar,
aren't
really
similar
behind
the
surface.