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

An Introduction to the Go Language

An Introduction to the Go Language

Go is an open source programming language developed at Google and designed for systems programming. Like C and C++, it is a compiled and statically typed language, with new features: garbage collection, various safety features and built-in concurrent primitives.

After only four years since its 1.0 release, we've seen many new products adopting Go as their main development language (Docker, CoreOS). Others refactored their existing services from dynamic languages to Go, significantly reducing their infrastructure costs.

Go's language specification is simple enough to hold in a programmer's head and has a "batteries included" standard library. With a simplicity approaching Python's, fast compilation times, executables that do not require a runtime and execution speeds approaching those of C++; it's not surprising that "fun" if often associated with the language.

This presentation will introduce the Go language to an audience of programmers; we will quickly review Go's simplified C-like structure, then we'll introduce Go's more advanced features.

More Decks by Moncton Developer User Group

Other Decks in Programming

Transcript

  1. Introduction to Go Moncton User Group 15 March 2016 Serge

    Léger Prototype Developer, National Research Council
  2. About Me Bachelor of Computer Science from UdM. Started my

    career in 1994 with a local startup - Dovico. Joined the public service in 1998 to help transition internal applications to Y2K. In 2007, joined National Research Council where I work with researchers in a number of different fields. C, C++, Perl, HTML+Javascript+CSS, Java, Python, Go
  3. Go Language (golang) Go is: Lightweight, avoids unnecessary repetition Object

    Oriented, but not in the usual way Concurrent, in a way that keeps you sane Designed for working programmers Compiled Statically typed Garbage collected Cross platform (Linux, Mac OSX, Windows, iOS, Android)
  4. History Project starts at Google in 2007 by engineers frustrated

    with the complexity of C++ Open source release in November 2009 Version 1.0 in March 2012 Version 1.1 in May 2013 Version 1.2 in December 2013 Version 1.3 in June 2014 Version 1.4 in December 2014 Version 1.5 in August 2015 - Compiler & tools now written in Go. GC is now concurrent. Version 1.6 in February 2016
  5. Hello World p a c k a g e m

    a i n i m p o r t " f m t " f u n c m a i n ( ) { f m t . P r i n t l n ( " H e l l o , W o r l d ! " ) } Run
  6. Types and Variables Go has many simple types: i n

    t , i n t 8 , i n t 1 6 , i n t 3 2 , i n t 6 4 u i n t , u i n t 8 , u i n t 1 6 , u i n t 3 2 , u i n t 6 4 , u i n t p t r f l o a t 3 2 , f l o a t 6 4 c o m p l e x 6 4 , c o m p l e x 1 2 8 b o o l , b y t e , r u n e , s t r i n g , e r r o r But these are the ones you'll use most often: i n t , f l o a t 6 4 , b o o l , b y t e , s t r i n g , e r r o r i n t and u i n t are the natural or most efficient size for integers on a particular platform, either 32 or 64 bits. All types have a zero value, which is used to initialize variables. 0 for numbers, f a l s e for booleans, " " for strings and n i l for everything else.
  7. Variable Declaration implicit type declaration short variable declaration unused variables

    p a c k a g e m a i n i m p o r t " f m t " v a r n a m e s t r i n g = " S e r g e " f u n c m a i n ( ) { v a r a g e i n t = 4 0 f m t . P r i n t f ( " H e l l o , W o r l d ! M y n a m e i s % s , a n d I ' m % d ( i s h ) . \ n " , n a m e , a g e ) } Run
  8. If statement A simple i f statement: i f x

    > 0 { r e t u r n y } Braces are mandatory, note the missing parentheses. The expression must evaluate to a boolean. There is also an optional e l s e statement: i f x > 0 { r e t u r n y } e l s e { r e t u r n z }
  9. If statement (continued) Cascading i f / e l s

    e statements i f x > 0 { r e t u r n y } e l s e i f x < 0 { r e t u r n z } e l s e i f x = = 0 { r e t u r n x } e l s e { / / C a n ' t r e a c h t h i s c o n d i t i o n ? } i f statements can also contain an initialization statement: i f x = s o m e F u n c t i o n ( ) ; x ! = 0 { r e t u r n z * x }
  10. If statement (playground) f u n c m a i

    n ( ) { p e r c e n t : = s o m e F u n c t i o n ( ) i f p e r c e n t < 5 0 { f m t . P r i n t l n ( " Y o u ' r e j u s t s t a r t i n g . " , p e r c e n t ) } e l s e { f m t . P r i n t l n ( " A l m o s t d o n e . " , p e r c e n t ) } } Run
  11. Switch statement A simple C-like s w i t c

    h statement: No b r e a k statement required, by default cases do not fall through. Use the f a l l t h r o u g h statement if that behavior is needed. f u n c m a i n ( ) { v a r h e a d s , t a i l s i n t s w i t c h c o i n F l i p ( ) { c a s e " h e a d s " : h e a d s + + c a s e " t a i l s " : t a i l s + + d e f a u l t : f m t . P r i n t l n ( " l a n d e d o n e d g e ! " ) } f m t . P r i n t l n ( h e a d s , t a i l s ) } Run
  12. Switch statement (continued) Instead of using f a l l

    t h r o u g h , case statements can be combined: f u n c m a i n ( ) { d a y O f W e e k : = t o d a y ( ) s w i t c h d a y O f W e e k { c a s e " S a t u r d a y " , " S u n d a y " : f m t . P r i n t l n ( " I t ' s t h e w e e k e n d ! " ) d e f a u l t : f m t . P r i n t l n ( " G e t u p a n d g o t o w o r k . " ) } } Run
  13. Switch statement (continued) The switch's expression is optional, so a

    s w i t c h statement can be used to replace long and complex i f / e l s e cascades: f u n c m a i n ( ) { d a y O f W e e k : = t o d a y ( ) w e e k N u m b e r : = w e e k ( ) s w i t c h { c a s e d a y O f W e e k = = " S a t u r d a y " | | d a y O f W e e k = = " S u n d a y " : f m t . P r i n t l n ( " I t ' s t h e w e e k e n d ! " ) c a s e d a y O f W e e k = = " T u e s d a y " & & w e e k N u m b e r % 2 = = 0 : f m t . P r i n t l n ( " P a y d a y ! " ) d e f a u l t : f m t . P r i n t l n ( " G e t u p a n d g o t o w o r k . " ) } } Run
  14. For statement Go has a single loop statement; the f

    o r loop has multiple forms: / / C s t y l e f o r i n i t i a l i z a t i o n ; c o n d i t i o n ; p o s t { } Both, initialization and post are optional: / / A t r a d i t i o n a l " w h i l e " l o o p f o r c o n d i t i o n { } condition is also optional and defaults to t r u e : / / a n i n f i n i t e l o o p f o r { }
  15. For statement (continued) b r e a k statement terminates

    the execution of the inner-most loop c o n t i n u e statement begins the next iteration of the inner-most loop There is also a "for-each" operator: r a n g e which operates on s t r i n g s , a r r a y s , s l i c e s , m a p s and c h a n n e l s . f u n c m a i n ( ) { / / C s t y l e l o o p f o r i : = 0 ; i < 7 ; i + + { f m t . P r i n t l n ( d w a r v e s [ i ] ) } f m t . P r i n t l n ( " - - - - - " ) / / U s i n g t h e r a n g e o p e r a t o r f o r i n d e x , n a m e : = r a n g e d w a r v e s { f m t . P r i n t l n ( i n d e x , n a m e ) } } Run
  16. Constants Constants are defined with the c o n s

    t keyword: c o n s t P i = 3 . 1 4 1 5 9 2 c o n s t ( a = 1 b = 2 ) c o n s t c , d = 3 , 4 f u n c m a i n ( ) { f m t . P r i n t l n ( P i , a , b ) / / c = 2 } Run
  17. Iota Go provides the i o t a constant generator

    to help construct constant values: c o n s t ( S u n d a y = 0 M o n d a y = 1 T u e s d a y = 2 W e d n e s d a y = 3 T h u r s d a y = 4 F r i d a y = 5 S a t u r d a y = 6 ) f u n c m a i n ( ) { f m t . P r i n t l n ( " S u n d a y = " , S u n d a y ) f m t . P r i n t l n ( " S a t u r d a y = " , S a t u r d a y ) } Run
  18. Custom Types Using the t y p e keyword we

    can create custom types: t y p e C o l o r u i n t 6 4 f u n c m a i n ( ) { v a r r e d C o l o r = 1 f m t . P r i n t l n ( r e d ) / / S a m e r u l e s a p p l y , y o u c a n n o t a s s i g n a C o l o r v a l u e t o a n u i n t 6 4 v a r i a b l e / / v a r v a l u e u i n t 6 4 / / v a l u e = r e d } Run
  19. Enumerated Types By combining constants and custom types we can

    create enumerated types: t y p e C o l o r u i n t 6 4 c o n s t ( R e d C o l o r = i o t a G r e e n B l u e ) or bit masks (from Go's n e t package) t y p e F l a g s u i n t c o n s t ( F l a g U p F l a g s = 1 < < i o t a F l a g B r o a d c a s t F l a g L o o p b a c k F l a g P o i n t T o P o i n t F l a g M u l t i c a s t )
  20. Arrays Arrays is a fixed-length sequence of zero or more

    elements. Since they are fixed- length arrays are rarely used. / / A n I P a d d r e s s v a r i p [ 4 ] b y t e i p [ 0 ] = 1 9 2 i p [ 1 ] = 1 6 8 i p [ 2 ] = 1 i p [ 3 ] = 1 / / T h e s a m e d e c l a r a t i o n v a r i p = [ 4 ] b y t e { 1 9 2 , 1 6 8 , 1 , 1 } / / A n o t h e r , t h e a r r a y s i z e i s c a l c u l a t e d b y t h e c o m p i l e r v a r i p = [ . . . ] b y t e { 1 9 2 , 1 6 8 , 1 , 1 } The built-in l e n function returns the number of elements in the array. Arrays are always passed by value, so use with care.
  21. Arrays (playground) p a c k a g e m

    a i n i m p o r t " f m t " f u n c m a i n ( ) { v a r d a y s O f W e e k = [ 7 ] s t r i n g { " S u n d a y " , " M o n d a y " , " T u e s d a y " , " W e d n e s d a y " , " T h u r s d a y " , " F r i d a y " , " S a t u r d a y " , } f m t . P r i n t l n ( " N u m b e r o f e n t r i e s : " , l e n ( d a y s O f W e e k ) ) f m t . P r i n t l n ( " F i r s t d a y : " , d a y s O f W e e k [ 0 ] ) f m t . P r i n t f ( " % T " , d a y s O f W e e k ) } Run
  22. Slices Slices represents variable-length sequences, like arrays, slices are indexable

    and have a length. Slices have another property: capacity. When a slice reaches its capacity, the Go runtime allocates more memory. / / A n I P a d d r e s s , u s i n g s l i c e s v a r i p [ ] b y t e i p = a p p e n d ( i p , 1 9 2 ) i p = a p p e n d ( i p , 1 6 8 ) i p = a p p e n d ( i p , 1 ) i p = a p p e n d ( i p , 1 ) / / T h e s a m e d e c l a r a t i o n v a r i p = [ ] b y t e { 1 9 2 , 1 6 8 , 1 , 1 } m a k e is a built-in function to create a new slice. l e n returns the length of the slice. c a p returns the capacity of the slice. a p p e n d appends elements to the slice.
  23. Slice Construction A slice can be constructed using the m

    a k e built-in function, providing a length and optionally an initial capacity. Slices are backed by an array which Go grows to accommodate new elements. f u n c m a i n ( ) { i d s : = m a k e ( [ ] i n t , 5 ) i d s [ 0 ] = 2 i d s [ 1 ] = 1 5 f m t . P r i n t l n ( " l e n = " , l e n ( i d s ) , " c a p = " , c a p ( i d s ) ) f m t . P r i n t l n ( i d s ) } Run
  24. Length and Capacity f u n c m a i

    n ( ) { v a r i d s = m a k e ( [ ] i n t , 0 , 1 0 ) f o r i : = 0 ; i < 1 0 0 ; i + + { f m t . P r i n t l n ( l e n ( i d s ) , c a p ( i d s ) ) i d s = a p p e n d ( i d s , i ) } / / T h e i n - m e m o r y l o c a t i o n o f t h e a r r a y c h a n g e s a s G o a l l o c a t e s m o r e m e m o r y f o r t h e / / g r o w i n g s l i c e . / / s l i c e P t r ( i d s ) } Run
  25. Slice Operators Go provides slice operators to create different views

    of the same in-memory array: v a r n e w S l i c e = s l i c e [ s t a r t : e n d ] / / s t a r t i s i n c l u s i v e a n d e n d i s e x c l u s i v e . f u n c m a i n ( ) { v a r d a y s O f W e e k = [ 7 ] s t r i n g { " S u n d a y " , " M o n d a y " , " T u e s d a y " , " W e d n e s d a y " , " T h u r s d a y " , " F r i d a y " , " S a t u r d a y " , } / / S l i c e f r o m a n a r r a y w e e k d a y s : = d a y s O f W e e k [ 1 : 6 ] / / R a n g e o p e r a t o r o v e r a s l i c e f o r i , v : = r a n g e w e e k d a y s { f m t . P r i n t l n ( i , v ) w e e k d a y s [ i ] = s t r i n g s . T o L o w e r ( v ) } f m t . P r i n t l n ( w e e k d a y s ) / / B u t t h e w e e k d a y s a n d d a y s O f W e e k s l i c e s a r e b a c k e d b y t h e s a m e a r r a y : / / f m t . P r i n t l n ( d a y s O f W e e k ) } Run
  26. Maps Maps are Go's implementation of associative arrays. Maps are

    expressed as follows: m a p [ K e y T y p e ] V a l u e T y p e f u n c m a i n ( ) { v a r c a p i t a l s = m a p [ s t r i n g ] s t r i n g { " N B " : " F r e d e r i c t o n " , " N S " : " H a l i f a x " , " Q C " : " Q u e b e c " , } f m t . P r i n t l n ( c a p i t a l s [ " N B " ] ) f m t . P r i n t l n ( c a p i t a l s [ " N S " ] ) / / C h e c k i f a k e y e x i s t s c i t y , o k : = c a p i t a l s [ " O N " ] i f o k { f m t . P r i n t l n ( " O n t a r i o ' s c a p i t a l i s " , c i t y ) } } Run
  27. Map Construction Maps must be created using the m a

    k e built-in function: m a k e is a built-in function to create a new map. l e n returns the length of the map. f u n c m a i n ( ) { c a p i t a l s : = m a k e ( m a p [ s t r i n g ] s t r i n g , 1 3 ) / / i n i t i a l s p a c e f o r 1 3 p r o v i n c e s c a p i t a l s [ " N B " ] = " F r e d e r i c t o n " c a p i t a l s [ " N S " ] = " H a l i f a x " c a p i t a l s [ " Q C " ] = " Q u e b e c " c a p i t a l s [ " O N " ] = " T o r o n t o " f o r p r o v i n c e , c i t y : = r a n g e c a p i t a l s { f m t . P r i n t f ( " % s ' s c a p i t a l i s % s \ n " , p r o v i n c e , c i t y ) } / / R e m o v e a n e n t r y f r o m t h e m a p d e l e t e ( c a p i t a l s , " N B " ) f m t . P r i n t l n ( l e n ( c a p i t a l s ) ) f m t . P r i n t l n ( c a p i t a l s ) } Run
  28. Structures A structure is a sequence of fields, each of

    which has a name, a type and optionally a f i e l d t a g which is metadata encoded in key/value pairs. t y p e P e r s o n s t r u c t { N a m e s t r i n g S t r e e t s t r i n g C i t y s t r i n g }
  29. Structures (playground) f u n c m a i n

    ( ) { v a r b o b P e r s o n b o b . N a m e = " B o b " b o b . S t r e e t = " 1 2 3 S t r e e t " b o b . C i t y = " S o m e w h e r e " / / U s i n g s t r u c t l i t e r a l s v a r c h a r l e s = P e r s o n { N a m e : " C h u c k " , S t r e e t : " 4 5 6 S t r e e t " , C i t y : " S o m e c i t y " , } f m t . P r i n t f ( f m t S t r i n g , " B o b " , " C h a r l e s " ) f m t . P r i n t f ( f m t S t r i n g , " - - - - - - - - - - - - " , " - - - - - - - - - - - - " ) f m t . P r i n t f ( f m t S t r i n g , b o b . N a m e , c h a r l e s . N a m e ) f m t . P r i n t f ( f m t S t r i n g , b o b . S t r e e t , c h a r l e s . S t r e e t ) f m t . P r i n t f ( f m t S t r i n g , b o b . C i t y , c h a r l e s . C i t y ) / / f m t . P r i n t f ( " % + v \ n " , b o b ) } Run
  30. Embedding structures and anonymous fields Instead of doing the following

    (which says E m p l o y e e as a field named P e r s o n of type P e r s o n ): t y p e E m p l o y e e s t r u c t { P e r s o n P e r s o n I d s t r i n g } We can omit the field name, this provides a convenient shortcut that allows the following shorter notation: E m p l o y e e . N a m e instead of E m p l o y e e . P e r s o n . N a m e . t y p e E m p l o y e e s t r u c t { P e r s o n I d s t r i n g }
  31. Embedding structures (playground) f u n c m a i

    n ( ) { v a r b o b E m p l o y e e b o b . I d = " 1 2 3 " b o b . N a m e = " B o b " b o b . S t r e e t = " 1 2 3 S t r e e t " b o b . C i t y = " S o m e w h e r e " / / U s i n g s t r u c t l i t e r a l s v a r c h a r l e s = E m p l o y e e { P e r s o n : P e r s o n { N a m e : " C h u c k " , S t r e e t : " 4 5 6 S t r e e t " , C i t y : " S o m e c i t y " } , I d : " 4 5 6 " , } f m t . P r i n t f ( f m t S t r i n g , " B o b " , " C h a r l e s " ) f m t . P r i n t f ( f m t S t r i n g , " - - - - - - - - - - - - " , " - - - - - - - - - - - - " ) f m t . P r i n t f ( f m t S t r i n g , b o b . I d , c h a r l e s . I d ) f m t . P r i n t f ( f m t S t r i n g , b o b . N a m e , c h a r l e s . N a m e ) f m t . P r i n t f ( f m t S t r i n g , b o b . S t r e e t , c h a r l e s . S t r e e t ) f m t . P r i n t f ( f m t S t r i n g , b o b . C i t y , c h a r l e s . C i t y ) / / f m t . P r i n t f ( " % + v \ n " , b o b ) } Run
  32. Functions Function declaration has a name, a list of parameters,

    an optional list of results, and a body: f u n c n a m e ( p a r a m e t e r - l i s t ) ( r e s u l t - l i s t ) { b o d y } f u n c m a x ( x i n t , y i n t ) i n t { i f x > y { r e t u r n x } e l s e { r e t u r n y } } f u n c m a i n ( ) { f m t . P r i n t l n ( m a x ( 1 0 , 5 ) ) } Run
  33. Functions with multiple return values Functions can return multiple values,

    this is often used to return error conditions. f u n c a d d A n d P r o d u c t ( x , y i n t ) ( i n t , i n t ) { r e t u r n x + y , x * y } f u n c s a f e A d d A n d P r o d u c t ( x , y i n t ) ( i n t , i n t , e r r o r ) { i f x < 0 | | y < 0 { r e t u r n 0 , 0 , e r r o r s . N e w ( " c a n ' t w o r k w i t h n e g a t i v e n u m b e r s " ) } r e t u r n x + y , x * y , n i l } f u n c m a i n ( ) { a , b : = a d d A n d P r o d u c t ( 2 , 5 ) f m t . P r i n t l n ( a , b ) / / x , y , e r r : = s a f e A d d A n d P r o d u c t ( - 2 , 5 ) / / i f e r r ! = n i l { / / f m t . P r i n t l n ( " e r r o r o c c u r e d : " , e r r ) / / } e l s e { / / f m t . P r i n t l n ( x , y ) / / } } Run
  34. Functions are first-class values f u n c s q

    u a r e ( n i n t ) i n t { r e t u r n n * n } f u n c n e g a t i v e ( n i n t ) i n t { r e t u r n - n } f u n c p r o d u c t ( n , m i n t ) i n t { r e t u r n n * m } f u n c m a i n ( ) { v a r f n f u n c ( i n t ) i n t / / a s s i g n t h e s q u a r e f u n c t i o n t o f f n = s q u a r e f m t . P r i n t l n ( f n ( 5 ) ) / / a s s i g n t h e n e g a t i v e f u n c t i o n t o f f n = n e g a t i v e f m t . P r i n t l n ( f n ( 5 ) ) / / a s s i g n t h e p r o d u c t f u n c t i o n t o f / / f n = p r o d u c t / / f m t . P r i n t l n ( f n ( 5 , 2 ) ) } Run
  35. Closures f u n c m a i n (

    ) { v a r f n f u n c ( i n t ) i n t / / a s s i g n t h e s q u a r e f u n c t i o n t o f f n = s q u a r e f m t . P r i n t l n ( f n ( 5 ) ) / / a s s i g n t h e n e g a t i v e f u n c t i o n t o f f n = n e g a t i v e f m t . P r i n t l n ( f n ( 5 ) ) / / a s s i g n t h e p r o d u c t f u n c t i o n t o f / / f n = p r o d u c t / / f m t . P r i n t l n ( f n ( 5 , 2 ) ) } f u n c n e w P r o d u c t F u n c ( n i n t ) f u n c ( i n t ) i n t { r e t u r n f u n c ( m i n t ) i n t { r e t u r n p r o d u c t ( n , m ) } } Run
  36. Variadic functions f u n c s u m (

    n u m b e r s . . . i n t ) ( t o t a l i n t ) { l o g . P r i n t f ( " % T l e n = % d \ n " , n u m b e r s , l e n ( n u m b e r s ) ) f o r _ , v : = r a n g e n u m b e r s { t o t a l + = v } r e t u r n } f u n c m a i n ( ) { f m t . P r i n t l n ( " S u m i s " , s u m ( ) ) f m t . P r i n t l n ( " S u m i s " , s u m ( 2 , 4 , 6 , 8 , 1 0 ) ) } Run
  37. Deferred Functions The execution of a function can be deferred

    until the enclosing function returns. This is normally used with paired operations like open/close or lock/unlock. f u n c r e a d F i l e ( f i l e n a m e s t r i n g ) { f h , e r r : = o s . O p e n ( f i l e n a m e ) i f e r r ! = n i l { r e t u r n } d e f e r f h . C l o s e ( ) }
  38. Deferred example Deferred calls are stacked, so deferred functions are

    called in LIFO order: f u n c s u m ( n u m b e r s . . . i n t ) ( t o t a l i n t ) { d e f e r l o g . P r i n t f ( " D e f e r r e d ? % T l e n = % d \ n " , n u m b e r s , l e n ( n u m b e r s ) ) f o r _ , v : = r a n g e n u m b e r s { d e f e r l o g . P r i n t l n ( v , t o t a l ) t o t a l + = v } l o g . P r i n t l n ( " l e a v i n g s u m ( ) " ) r e t u r n } f u n c m a i n ( ) { f m t . P r i n t l n ( s u m ( 2 , 4 , 6 , 8 , 1 0 ) ) } Run
  39. Objects In Go an object is simply a variable or

    value that has methods, a method is a function associated with a particular type. Here is generic method definition: f u n c ( r e c e i v e r ) n a m e ( p a r a m e t e r - l i s t ) ( r e s u l t - l i s t ) { b o d y } There is no inheritance in Go instead types are composed. There are no constructors or destructors either.
  40. Objects Example t y p e P o i n

    t s t r u c t { X , Y f l o a t 6 4 } f u n c ( p o i n t P o i n t ) D i s t a n c e ( q P o i n t ) f l o a t 6 4 { r e t u r n m a t h . H y p o t ( p o i n t . X - q . X , p o i n t . Y - q . Y ) } f u n c m a i n ( ) { v a r p = P o i n t { 3 , 5 } d i s t : = p . D i s t a n c e ( P o i n t { 1 , 0 } ) f m t . P r i n t l n ( d i s t ) } Run
  41. Methods with Pointer Receivers The P o i n t

    . D i s t a n c e method uses a pass-by-value receiver meaning that any changes made to the p o i n t variable will be lost. Instead we can use a pointer receiver f u n c ( p o i n t * P o i n t ) S c a l e B y ( n f l o a t 6 4 ) { p o i n t . X * = n p o i n t . Y * = n } f u n c m a i n ( ) { v a r p = P o i n t { 3 , 5 } f m t . P r i n t l n ( " B e f o r e : " , p ) p . S c a l e B y ( 3 ) f m t . P r i n t l n ( " A f t e r : " , p ) d i s t : = p . D i s t a n c e ( P o i n t { 1 , 0 } ) f m t . P r i n t l n ( d i s t ) } Run
  42. Object Composition t y p e C o l o

    r e d P o i n t s t r u c t { P o i n t C o l o r s t r i n g } f u n c m a i n ( ) { c p R e d : = C o l o r e d P o i n t { P o i n t { 1 , 2 } , " r e d " } c p B l u e : = C o l o r e d P o i n t { P o i n t { 3 , 6 } , " b l u e " } c p R e d . S c a l e B y ( 3 ) / / C o l o r e d P o i n t " i n h e r i t s " t h e P o i n t m e t h o d s f m t . P r i n t l n ( c p R e d . D i s t a n c e ( P o i n t { 1 , 0 } ) ) f m t . P r i n t l n ( c p B l u e . D i s t a n c e ( P o i n t { 1 , 0 } ) ) } Run
  43. Interfaces Interfaces in Go are similar to interfaces from Java.

    Here is a generic interface definition: t y p e N a m e i n t e r f a c e { / / L i s t o f f u n c t i o n s . . . f n N a m e 1 ( p a r a m e t e r - l i s t ) ( r e s u l t - l i s t ) f n N a m e 2 ( p a r a m e t e r - l i s t ) ( r e s u l t - l i s t ) f n N a m e 3 ( p a r a m e t e r - l i s t ) ( r e s u l t - l i s t ) / / . . . o r l i s t o f o t h e r i n t e r f a c e s I n t e r f a c e N a m e 2 } There is no requirement to declare that an object implements an interface. The compiler ensures that an object properly implements the interface. Interfaces in Go are normally small with only a few methods.
  44. Interfaces from Go's io package t y p e R

    e a d e r i n t e r f a c e { R e a d ( p [ ] b y t e ) ( n i n t , e r r e r r o r ) } t y p e C l o s e r i n t e r f a c e { C l o s e ( ) e r r o r } / / I n t e r f a c e e m b e d d i n g t y p e R e a d C l o s e r i n t e r f a c e { R e a d e r C l o s e r }
  45. Implementation of the io.Reader interface t y p e m

    y R e a d e r u i n t 8 f u n c ( r m y R e a d e r ) R e a d ( b u f [ ] b y t e ) ( i n t , e r r o r ) { / / i o . R e a d e r " i m p l e m e n t a t i o n " f o r i : = r a n g e b u f { b u f [ i ] = b y t e ( r ) } r e t u r n l e n ( b u f ) , n i l } f u n c m a i n ( ) { v a r r e a d e r m y R e a d e r = 6 5 / / R e a d 1 0 b y t e s f r o m t h e r e a d e r . . . v a r b u f = m a k e ( [ ] b y t e , 1 0 ) r e a d e r . R e a d ( b u f ) f m t . P r i n t l n ( b u f ) i o . C o p y ( o s . S t d o u t , r e a d e r ) } Run
  46. Interfaces t y p e S h a p e

    i n t e r f a c e { A r e a ( ) f l o a t 6 4 } t y p e S q u a r e s t r u c t { s i d e f l o a t 6 4 } f u n c ( s q * S q u a r e ) A r e a ( ) f l o a t 6 4 { r e t u r n s q . s i d e * s q . s i d e } t y p e C i r c l e s t r u c t { r a d i u s f l o a t 6 4 } f u n c ( c * C i r c l e ) A r e a ( ) f l o a t 6 4 { r e t u r n m a t h . P i * m a t h . P o w ( c . r a d i u s , 2 ) }
  47. Interfaces (playground) t y p e R e c t

    s t r u c t { w i d t h , h e i g h t i n t } f u n c ( r * R e c t ) A r e a ( ) i n t { r e t u r n r . w i d t h * r . h e i g h t } f u n c m a i n ( ) { v a r c = & C i r c l e { 5 } v a r s = & S q u a r e { 7 } v a r r = & R e c t { 7 , 5 } / / b o r i n g . . . c a l l t h e A r e a m e t h o d d i r e c t l y f m t . P r i n t l n ( c . A r e a ( ) ) f m t . P r i n t l n ( s . A r e a ( ) ) f m t . P r i n t l n ( r . A r e a ( ) ) / / c a l l t h e A r e a m e t h o d v i a t h e S h a p e i n t e r f a c e / / s h a p e s : = [ ] S h a p e { c , s , r } / / f o r _ , s h a p e : = r a n g e s h a p e s { / / f m t . P r i n t l n ( s h a p e . A r e a ( ) ) / / } } Run
  48. Empty Interface An empty interface is an interface with no

    methods -- meaning that everything in Go satisfies the empty interface. This is similar to Java's O b j e c t . The empty interface type is written i n t e r f a c e { } : v a r f i n t e r f a c e { } f u n c d e s c r i b e ( v i n t e r f a c e { } ) { f m t . P r i n t f ( " ( % T , % v ) \ n " , v , v ) } f u n c m a i n ( ) { v a r f 3 2 , f 6 4 = f l o a t 3 2 ( 2 1 ) , f l o a t 6 4 ( 4 2 ) v a r i , s = 1 0 , " A s t r i n g " d e s c r i b e ( f 3 2 ) d e s c r i b e ( f 6 4 ) d e s c r i b e ( i ) d e s c r i b e ( & i ) d e s c r i b e ( s ) } Run
  49. Type Assertions Sometimes it is useful to either convert an

    interface to its underlying type or to convert it to another interface. f u n c r e a d A n d C l o s e ( r i o . R e a d e r ) { / / . . . r e a d d a t a f r o m r . . . / / C l o s e t h e f i l e i f i t i m p l e m e n t s t h e i o . C l o s e r i n t e r f a c e i f c l o s e r , o k : = r . ( i o . C l o s e r ) ; o k { / / T y p e A s s e r t i o n t o a n o t h e r i n t e r f a c e f m t . P r i n t l n ( " C l o s i n g t h e f i l e " ) c l o s e r . C l o s e ( ) } / / I s t h i s a m y R e a d e r ? i f _ , o k : = r . ( m y R e a d e r ) ; o k { / / T y p e A s s e r t i o n t o t h e i m p l e m e n t a t i o n t y p e f m t . P r i n t l n ( " Y o u ' v e b e e n u s i n g a d u m b r e a d e r . " ) } } f u n c m a i n ( ) { v a r r e a d e r m y R e a d e r = 6 5 r e a d A n d C l o s e ( o s . S t d i n ) r e a d A n d C l o s e ( r e a d e r ) } Run
  50. A complex type assertion example f u n c d

    o u b l e ( x i n t e r f a c e { } ) i n t e r f a c e { } { i f i , o k : = x . ( i n t ) ; o k { r e t u r n i * 2 } e l s e i f i P t r , o k : = x . ( * i n t ) ; o k { r e t u r n ( * i P t r ) * 2 } e l s e i f f 3 2 , o k : = x . ( f l o a t 3 2 ) ; o k { r e t u r n f 3 2 * 2 } e l s e i f f 6 4 , o k : = x . ( f l o a t 6 4 ) ; o k { r e t u r n f 6 4 * 2 } e l s e { l o g . P r i n t f ( " u n s u p p o r t e d t y p e : % T \ n " , x ) } p a n i c ( " u n s u p p o r t e d t y p e " ) }
  51. From Type Assertions to Type Switches f u n c

    m a i n ( ) { f m t . P r i n t l n ( d o u b l e ( f l o a t 3 2 ( 5 . 5 ) ) ) f m t . P r i n t l n ( d o u b l e ( f l o a t 6 4 ( 5 . 5 ) ) ) i : = 1 5 f m t . P r i n t l n ( d o u b l e ( i ) ) f m t . P r i n t l n ( d o u b l e ( & i ) ) } Run
  52. Type Switches f u n c t r i p

    l e ( x i n t e r f a c e { } ) i n t e r f a c e { } { s w i t c h x : = x . ( t y p e ) { c a s e i n t : r e t u r n x * 3 c a s e f l o a t 3 2 : r e t u r n x * 3 c a s e f l o a t 6 4 : r e t u r n x * 3 c a s e * i n t : r e t u r n * x * 3 d e f a u l t : l o g . P r i n t f ( " u n s u p p o r t e d t y p e : % T \ n " , x ) } p a n i c ( " u n s u p p o r t e d t y p e " ) }
  53. Type Switches f u n c m a i n

    ( ) { f m t . P r i n t l n ( d o u b l e ( f l o a t 3 2 ( 5 . 5 ) ) ) f m t . P r i n t l n ( d o u b l e ( f l o a t 6 4 ( 5 . 5 ) ) ) i : = 1 5 f m t . P r i n t l n ( d o u b l e ( i ) ) f m t . P r i n t l n ( d o u b l e ( & i ) ) } Run
  54. Go supports concurrency Go provides: concurrent execution (goroutines) synchronization and

    messaging (channels) multi-way concurrent control (select)
  55. Goroutines are not threads They're a bit like threads, but

    cheaper. Small and resizeable stacks (~2KB versus ~1MB for threads). Common to launch a large number of goroutines during the life of an application. The Go runtime multiplexes goroutines across OS threads.
  56. Goroutines (launch and forget) f u n c s a

    y ( s t r s t r i n g ) { f m t . P r i n t l n ( s t r ) } f u n c m a i n ( ) { g o s a y ( " H e l l o , W o r l d ! " ) s a y ( " A l l D o n e ! " ) t i m e . S l e e p ( 5 0 0 * t i m e . M i l l i s e c o n d ) } Run
  57. Channels Channels provide communication and synchronization mechanisms between goroutines. Each

    channel provides a conduit for values of a particular types. v a r c h I n t c h a n i n t / / A c h a n n e l o f i n t e g e r s v a r c h P t r c h a n * i n t / / A c h a n n e l o f i n t e g e r p o i n t e r s A channel is created with the built-in m a k e function: c h I n t = m a k e ( c h a n i n t ) c h I n t < - 4 2 / / S e n d a v a l u e o n t h e c h a n n e l ( b l o c k s u n t i l a n o t h e r g o r o u t i n e r e a d s f r o m c h I n t ) / / R e a d s a v a l u e ( b l o c k s u n t i l a n o t h e r g o r o u t i n e i s w r i t i n g t o c h I n t ) v : = < - c h I n t / / C h a n n e l s c a n b e u s e d w i t h f o r / r a n g e l o o p f o r v : = r a n g e c h I n t { / / D o s o m e t h i n g w i t h v } / / C l o s e a c h a n n e l c l o s e ( c h I n t )
  58. Ping-Pong t y p e B a l l s

    t r u c t { h i t s i n t } f u n c m a i n ( ) { t a b l e : = m a k e ( c h a n * B a l l ) g o p l a y e r ( " p i n g " , t a b l e ) g o p l a y e r ( " p o n g " , t a b l e ) t a b l e < - n e w ( B a l l ) / / g a m e o n ; t o s s t h e b a l l t i m e . S l e e p ( 1 * t i m e . S e c o n d ) < - t a b l e / / g a m e o v e r ; g r a b t h e b a l l } f u n c p l a y e r ( n a m e s t r i n g , t a b l e c h a n * B a l l ) { f o r { b a l l : = < - t a b l e b a l l . h i t s + + f m t . P r i n t l n ( n a m e , b a l l . h i t s ) t i m e . S l e e p ( 1 0 0 * t i m e . M i l l i s e c o n d ) t a b l e < - b a l l } } Run
  59. More Concurrency Go has a s e l e c

    t statement that can multiplex multiple channels, similar to C's s e l e c t ( ) function for file handles or a s w i t c h statement. s e l e c t { c a s e v : = < - c h 1 : / / d o s o m e t h i n g w i t h v c a s e c h 2 < - " a s t r i n g " : d e f a u l t : / / d e f a u l t i s o p t i o n a l , i f i t ' s a b s e n t t h e w h o l e s e l e c t b l o c k s u n t i l a c a s e i s r e a d y } Go also has a package s y n c and s y n c / a t o m i c that provides regular synchronization mechanisms: sync.Mutex, sync.RWMutex, sync.WaitGroup atomic.CompareAndSwap, atomic.AddInt
  60. Workspace Organization The only configuration most users ever need is

    the GOPATH environment variable. e x p o r t G O P A T H = $ H O M E / p r o j e c t s / p i v o t t a b l e The GOPATH variable is similar to Java's CLASSPATH variable and can contain more than one entry, seperated by : (or ; on Windows). A workspace contains at least one directory s r c which contains your project's source files (and third-party packages you may have installed). The Go tools will generate two other directories: b i n contains your project's executable files p k g contains the compiled packages
  61. Package Construction $ G O P A T H /

    ├ ─ ─ b i n ├ ─ ─ p k g └ ─ ─ s r c └ ─ ─ p t ├ ─ ─ c m d │ └ ─ ─ p i v o t t a b l e ├ ─ ─ i o u t i l └ ─ ─ r e p o r t └ ─ ─ t e x t In the example above, the pivottable project defines the following packages: i m p o r t " p t " i m p o r t " p t / i o u t i l " i m p o r t " p t / r e p o r t " i m p o r t " p t / r e p o r t / t e x t "
  62. Package Construction A package is defined by one or more

    . g o files, each declaring the same package namespace using the p a c k a g e statement. By convention, the directory name and the package name are the same, but it's not a requirement. $ G O P A T H / └ ─ ─ s r c └ ─ ─ p t ├ ─ ─ i o u t i l │ ├ ─ ─ c o l r e a d e r . g o │ ├ ─ ─ c o l r e a d e r _ t e s t . g o │ ├ ─ ─ c p u p r o f i l e . g o │ ├ ─ ─ i o . g o │ ├ ─ ─ r a n d s e e d . g o │ ├ ─ ─ r e a d e r . g o │ ├ ─ ─ r e a d e r _ t e s t . g o │ ├ ─ ─ t r a c e p r o f i l e . g o │ ├ ─ ─ w r i t e r . g o │ └ ─ ─ w r i t e r _ t e s t . g o
  63. Import Paths i m p o r t ( "

    f m t " " p t / i o u t i l " " g i t h u b . c o m / c k e e k y b i t s / i s " " g o o g l e . g o l a n g . o r g / a p i / c a l e n d a r / v 3 " / / a c t u a l p a c k a g e n a m e i s " c a l e n d a r " ) Import paths are only strings and have no meaning to the Go language, they're only used for looking up packages. Go tools will use G O R O O T and G O P A T H to find the actual packages: $ G O R O O T / s r c / f m t $ G O P A T H / s r c / p t / i o u t i l $ G O P A T H / s r c / g i t h u b . c o m / c k e e k y b i t s / i s $ G O P A T H / s r c / g o o g l e . g o l a n g . o r g / a p i / c a l e n d a r / v 3
  64. Standard Library Go's standard library has about 150 packages: Input/Output

    (bufio, io, os, path, path/filepath) Networking (net, net/http) Types (strings, bytes, errors, time, strconv) Testing (testing) Reflection (reflect) Regular Expression (regexp) Many more... https://golang.org/pkg/ (https://golang.org/pkg/)
  65. References The Go Programming Language, Alan A. A. Donovan &

    Brian W. Kernighan https://tour.golang.org/ (https://tour.golang.org/) https://golang.org/doc/effective_go.html (https://golang.org/doc/effective_go.html) https://golang.org/ref/spec (https://golang.org/ref/spec) https://golang.org/pkg (https://golang.org/pkg)
  66. Thank you Serge Léger Prototype Developer, National Research Council https://github.com/sergeleger/mug

    (https://github.com/sergeleger/mug) @sergeleger (http://twitter.com/sergeleger)