Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Embedding: It sure is weird

Avatar for Stabby Stabby
March 10, 2018

Embedding: It sure is weird

A talk all about the strange quirks and edge cases of embedding in golang. This is the version delivered at Gophercon India 2018

Avatar for Stabby

Stabby

March 10, 2018

Other Decks in Technology

Transcript

  1. OBLIGATORY OPENING SLIDES WHAT AM I HERE TO TALK ABOUT?

    ▸ Embedding! ▸ What is it, and how does it work? ▸ More accurately, a lot of ways it does not work. ▸ Useful ways to apply embedding for fun and profit!* ▸ *Neither fun nor profit guaranteed. ▸ Sweet pictures of my awesome dog!
  2. EMBEDDING IS NOT BETTER THAN “CLASSICAL” INHERITANCE. IT’S A DIFFERENT

    TOOL FOR A DIFFERENT PROBLEM Me FUN QUOTE FOR YOU TO DISAGREE WITH
  3. WHAT IS EMBEDDING? DEFINING EMBEDDING AND COMPOSITION ▸ Embedding is

    a way to re-use existing structs and interfaces via composition ▸ Think more behavior over lineage ▸ Embedding to define structure is perfectly valid, though ▸ Sideways Inheritance ▸ Embed to define the API of a struct or interface github.com/StabbyCutyou/embeddingtalk
  4. WHAT IS EMBEDDING? HOW DOES IT DIFFER FROM “CLASSICAL” INHERITANCE?

    ▸ It does not establish nor imply a “base class / sub class” relationship. ▸ “Is a” VS “Has a” style relationship ▸ Method dispatch mostly works as you think it would ▸ There are some interesting edge regarding “where” the method gets called from ▸ The embedding type cannot be exchanged for the embedded type ▸ You can’t pass in a Corgi to a method which wants a Dog github.com/StabbyCutyou/embeddingtalk
  5. WHAT IS EMBEDDING? CLASSICAL INHERITANCE ▸ Kingdom - Animalia ▸

    Phylum - Chordata ▸ Class - Mammalia ▸ Order - Carnivora ▸ Family - Canidae ▸ Genus - Canis ▸ Species - Canis Lupus ▸ Subspecies - Canis Lupus Familiaris ▸ Breed - Pembroke Welsh Corgi github.com/StabbyCutyou/embeddingtalk
  6. WHAT IS EMBEDDING? WELL, WHAT DOES THE SPEC SAY? ▸

    More than it used to! ▸ “A field declared with a type but no explicit field name is an embedded field. An embedded field must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.” ▸ “An interface T may use a (possibly qualified) interface type name E in place of a method specification. This is called embedding interface E in T; it adds all (exported and non- exported) methods of E to the interface T. An interface type T may not embed itself or any interface type that embeds T, recursively.” ▸ It defines a series of rules for determining how promotion works, but is light on examples. github.com/StabbyCutyou/embeddingtalk
  7. HOW DOES EMBEDDING WORK? SELECTORS ▸ Selectors are expressions that

    denote fields or methods available on an object ▸ “For a value x of type T or *T where T is not a pointer or interface type, x.f denotes the field or method at the shallowest depth in T where there is such an f. If there is not exactly one f with shallowest depth, the selector expression is illegal.” ▸ Example: t.F is a simple selector github.com/StabbyCutyou/embeddingtalk
  8. HOW DOES EMBEDDING WORK? METHODSETS ▸ MethodSets are the collection

    of all available methods with a receiver of type T. ▸ For an interface, the interface is it’s own MethodSet ▸ Keyword: Set github.com/StabbyCutyou/embeddingtalk
  9. HOW DOES EMBEDDING WORK? PROMOTION ▸ Promotion occurs when type

    E is embedded into type T, such that a field or method on E can be accessed at the shallowest depth of an instance of T. ▸ If E has field or method X, and T embeds E, X is promoted if T doesn’t already contain X ▸ Promoted methods and fields are called on their original receiver ▸ If T already contains X, X is called on T, never E github.com/StabbyCutyou/embeddingtalk
  10. PROMOTION COMMOTION EMBEDDING MULTIPLE STRUCTS ▸ You can embed more

    than one type into another type ▸ You can even nest embeddings ▸ You cannot embed the same type more than once ▸ What happens when you embed multiple types that result in ambiguous selectors? ▸ The compiler lets you do it! ▸ However, it does not let you invoke those selectors! github.com/StabbyCutyou/embeddingtalk
  11. PROMOTION COMMOTION EMBEDDING EXPORTED TYPES ▸ You can embed any

    exported type from any package ▸ You cannot embed types from different packages with the same name ▸ What happens to un-exported fields and methods from exported types? ▸ There is a long standing “bug” in the reflect package about this! ▸ https://github.com/golang/go/issues/4876 ▸ It’s currently managed via a comment in the standard lib ▸ “Broken as intended” github.com/StabbyCutyou/embeddingtalk
  12. PROMOTION COMMOTION EMBEDDING INTERFACES IN STRUCTS ▸ You can do

    it ▸ Embed abstract behaviors instead of concrete behaviors ▸ Don’t panic! ▸ What about embedding 2 or more interfaces… ▸ With duplicate methods? github.com/StabbyCutyou/embeddingtalk
  13. PROMOTION COMMOTION MARSHALING AND UNMARSHMALING ▸ You can expose and

    receive data for embedded types ▸ Careful! With go 1.10, un-exported embedded types changed! ▸ You can add tags to embedded types ▸ Careful! This changes the behavior of marshaling! ▸ You can override and block out the marshaling behavior of embedded types ▸ Lots of examples, but little time to cover them all ▸ Let’s cover 1 specific case… github.com/StabbyCutyou/embeddingtalk
  14. PROMOTION COMMOTION HIDING SECRETS ▸ Embed a DomainModel in a

    ViewModel ▸ Use promotion semantics to hide private information ▸ Watch out for tricky marshal and unmarshal behaviors w/r/t tags on embedded fields ▸ The shape of raw data also matters when combined with embedded tags ▸ See “7.marshaling/tags” of the examples on github ▸ TL;DR; ▸ Don’t rely on “-“ to ignore embedded secrets ▸ Redefine the field, use the same struct tag name, and include “omitempty” or else! github.com/StabbyCutyou/embeddingtalk
  15. ROUNDUP EMBEDDING ▸ It’s not better than inheritance ▸ It’s

    different ▸ The spec has been updated to include more context around embedding recently ▸ Selectors and MethodSets are pretty simple ▸ Promotion is where it gets tricky ▸ You can embed interfaces, but it gets weird github.com/StabbyCutyou/embeddingtalk
  16. ROUNDUP EMBEDDING ▸ Methods and Fields are always called relative

    to their original receiver ▸ Once you go “down”, you can never go back up - only “sideways” or further “down” ▸ Once you embed a value, don’t touch it again ▸ Only interact with embedded types via the promotion exposed by their embedding type ▸ Or, throw caution to the wind ▸ I’m not the Go police github.com/StabbyCutyou/embeddingtalk