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

Golang Notes

Golang Notes

Traps that are not so obvious to beginners

Tevin Zhang

June 29, 2016
Tweet

More Decks by Tevin Zhang

Other Decks in Programming

Transcript

  1. Example Goroutine will hang forever if timeout f u n

    c m a i n ( ) { c h : = m a k e ( c h a n b o o l ) g o f u n c ( ) { d e f e r c l o s e ( c h ) / / d o s o m e t h i n g h e a v y c h < - t r u e / / s e n d r e s u l t } ( ) / / w a i t u n t i l t i m e o u t s e l e c t { c a s e r : = < - c h : p r i n t l n ( " T h e r e s u l t i s : " , r ) c a s e < - t i m e . A f t e r ( t i m e . S e c o n d ) : } } Run
  2. Solution Add bu er to chan, or: f u n

    c s o l u t i o n 2 ( ) { c h : = m a k e ( c h a n b o o l ) g o f u n c ( ) { d e f e r c l o s e ( c h ) / / d o s o m e t h i n g h e a v y s e l e c t { c a s e c h < - t r u e : / / s e n d r e s u l t d e f a u l t : / / d o n o t h i n g i f n o b o d y ' s e x p e c t i n g i t } } ( ) / / w a i t u n t i l t i m e o u t s e l e c t { c a s e r : = < - c h : p r i n t l n ( " T h e r e s u l t i s : " , r ) c a s e < - t i m e . A f t e r ( t i m e . S e c o n d ) : } }
  3. What's the output? f u n c m a i

    n ( ) { s : = [ ] i n t { 1 } o n e : = & s [ 0 ] s = a p p e n d ( s , 2 ) f o r i : = r a n g e s { s [ i ] + + } p r i n t l n ( * o n e , s [ 0 ] , s [ 1 ] ) / / W h a t ' s t h e o u t p u t ? } Run
  4. Slice is not Array The size of an array is

    part of the type of array, thus xed Slice is not array, it's a descriptor of array It consists of a pointer to array( rst element), len, cap Append copies the underlying array when insu cient capacity is encountered
  5. What's the capacity of the slice? f u n c

    m a i n ( ) { s : = m a k e ( [ ] i n t , 5 1 2 ) f m t . P r i n t l n ( " L e n : " , l e n ( s ) , " C a p : " , c a p ( s ) ) s = a p p e n d ( s , 0 ) f m t . P r i n t l n ( " L e n : " , l e n ( s ) , " C a p : " , c a p ( s ) ) } Run
  6. How about 1024 instead of 512? f u n c

    m a i n ( ) { s : = m a k e ( [ ] i n t , 1 0 2 4 ) f m t . P r i n t l n ( " L e n : " , l e n ( s ) , " C a p : " , c a p ( s ) ) s = a p p e n d ( s , 0 ) f m t . P r i n t l n ( " L e n : " , l e n ( s ) , " C a p : " , c a p ( s ) ) } Run
  7. How / / g o 1 . 6 . 2

    / s r c / r u n t i m e / s l i c e . g o / / g r o w s l i c e h a n d l e s s l i c e g r o w t h d u r i n g a p p e n d . / / I t i s p a s s e d t h e s l i c e t y p e , t h e o l d s l i c e , a n d t h e d e s i r e d n e w m i n i m u m c a p a c i t y , / / a n d i t r e t u r n s a n e w s l i c e w i t h a t l e a s t t h a t c a p a c i t y , w i t h t h e o l d d a t a / / c o p i e d i n t o i t . f u n c g r o w s l i c e ( t * s l i c e t y p e , o l d s l i c e , c a p i n t ) s l i c e { / / . . . f o r { i f o l d . l e n < 1 0 2 4 { n e w c a p + = n e w c a p } e l s e { n e w c a p + = n e w c a p / 4 } i f n e w c a p > = c a p { b r e a k } } / / . . . }
  8. While strings don't Copy happens during the conversion between [

    ] b y t e and s t r i n g These are expensive: bytes = []byte(str) str = string(bytes)
  9. Tips Avoid conversion as much as you could, or you

    make garbage lose performance Choose either [ ] b y t e or s t r i n g wisely There are H a s P r e f i x , T r i m S p a c e , S p l i t etc in the bytes package, just as in the strings package
  10. Animal (Parent class): t y p e A n i

    m a l s t r u c t { } f u n c ( a * A n i m a l ) E a t ( ) { f m t . P r i n t l n ( " E a t i n g . . . " ) } f u n c ( a * A n i m a l ) F e e d ( ) { / / p r e p a r e f o o d a . E a t ( ) / / c l e a n u p }
  11. Dog (Child of Animal): t y p e D o

    g s t r u c t { A n i m a l } f u n c ( d * D o g ) E a t ( ) { f m t . P r i n t l n ( " D o g e a t i n g . . . " ) } Let's see: f u n c m a i n ( ) { d : = D o g { } d . F e e d ( ) } Run
  12. Why By embedding A n i m a l into

    D o g the only thing you got is D o g . F e e d ( ) and it doesn't work with D o g . E a t ( ) . There are NO relationships between A n i m a l and D o g , the A n i m a l don't know and can't reach the D o g In other words: You got nothing from embedding, it's just a syntactic sugar (in this case).
  13. Animal t y p e E a t e r

    i n t e r f a c e { E a t ( ) } t y p e A n i m a l s t r u c t { E a t e r } f u n c ( a * A n i m a l ) F e e d ( ) { / / p r e p a r e f o o d a . E a t e r . E a t ( ) / / c l e a n u p }
  14. Dog (same as before) t y p e D o

    g s t r u c t { } f u n c ( d * D o g ) E a t ( ) { f m t . P r i n t l n ( " D o g e a t i n g . . . " ) } Here comes the di erence: f u n c m a i n ( ) { d : = A n i m a l { E a t e r : & D o g { } } d . F e e d ( ) } Run
  15. Embedding is not Inheritance, not even close! Anonymous eld is

    just like ordinary one, nothing magic. There are NO relationships between the embedded eld and the enclosing struct, the former don't know the existance of the later thus can't reach to it.
  16. Takeaways Slice is not array Pre-allocate for better performance and

    less garbage Avoid conversion between []byte and string, or you make garbage lose performance Whenever you start a goroutine you need to know where it dies Embedding is not Inheritance, use Interface