// create a nil slice of integers
  var arr []int
  // create an empty slice of integers
  arr := make([]int, 0)
  // works just fine
  for range something
  {
    run()
  }
  type BroadcastIface interface {
    Broadcast()
  }
  var temp interface{} = somevar
	_, ok := temp.(BroadcastIface)
  if !ok {
    fmt.Println("somevar does not implement BroadcastIface")
  }
  type person struct {
    Name    string  `json:"name"`
    Balance float64 `json:"balance,string"`
  }
  p := person{Name: "Steve", Balance: 200}
	jsonData, _ := json.Marshal(p)
	fmt.Println(string(jsonData))
  // {"name":"Steve","balance":"200"}
  // Note balance of type float64 is automatically converted into string
  // an empty structure that occupies zero bytes of storage
  // struct{}{}
  // can be used instead of bool or int in done channel
  done := make(chan struct{})
  // ...
  done <- struct{}{}
  type CalcIface interface {
    Add(a, b int) int
    Sub(a, b int) int
  }
  // No receiver capture funcs, empty struct to group methods togetehr
  type calc struct{}
  func (calc) Add(a, b int) int { return a+b }
  func (calc) Sub(a, b int) int { return a-b }
  // only expose Calc and CalcIface
  var Calc CalcIface = calc{}
  type people []string
  func (p *people) add(name string) {
    *p = append(*p, name)
  }
  grp := people{"John", "Steve"}
	grp.add("Mike")
	fmt.Println(grp)
  // [John Steve Mike]
  type SquarerIface interface {
    DoSquare(int) int
  }
  type ProcessFunc func(int) int
  func (pf ProcessFunc) DoSquare(i int) int {
    return pf(i)
  }
  myfunc := func(i int) int { return i * i }
	var sq SquarerIface = ProcessFunc(myfunc)
	fmt.Println(sq.DoSquare(5))
  // 25
}
  func StartCounterFrom(start int) func() int {
    return func() int {
      start = start + 1
      return start
    }
  }
  incr := StartCounterFrom(10)
  fmt.Println(incr()) //prints 11
  fmt.Println(incr()) //prints 12
  // Example 1
  type Ball struct {
    Radius   int
    Material string
  }
  func (b Ball) Bounce() {
    fmt.Printf("Bouncing ball %+v\n", b)
  }
  type Football struct {
    Ball // embedding  struct Ball
  }
  fb := Football{Ball{Radius: 5, Material: "leather"}}
  fb.Ball.Bounce() // works
  fb.Bounce() // works
  // Example 2
  // field collisions
  type A struct {
    x int32
  }
  type B struct {
    x int32
  }
  type C struct {
    A
    B
  }
  c := C{A{1}, B{2}}
  //fmt.Println(c.x) // Error, ambiguous
  fmt.Println(c.A.x) // Ok, 1
  fmt.Println(c.B.x) // Ok, 2
  // Example 3
  // composing interfaces
  type area interface {
    area() float64
  }
  type perimeter interface {
    perimeter() float64
  }
  // Composing Interfaces
  type geometry interface {
    area
    perimeter
  }
  // Example 4
  // interfaces in struct
  type animal interface {
    walk()
  }
  type pet1 struct {
    name string
  }
  func (p1 pet1) walk() {
    fmt.Println("Walking...")
  }
  type pet2 struct {
    animal
    name string
  }
  var p1 animal = &pet1{name: "Peggy"}
  var p2 animal = &pet2{name: "Meggy"}
	p1.walk() // ok
  p2.walk() // finds method, but will be intialised with the zero value of the interface which is nil. As walk in not implemented, a panic will occur
  var RecordError = error.New("Record not found")
  // export and use RecordError
  // usage in another file
  func New() error {
    // ...
    if false {
      return RecordError
    }
  }
  // checking
  if err ==  RecordError {
    fmt.Println("I know this is record error")
  } else {
    fmt.Println("Something werid happen")
  }
  func (u User) Make(v interface{}) {
    switch v.(type) { // or t := v.(type) and use t in later cases
    case string:
      // ...
    case int:
      // ...
    default:
      // ...
    }
  }
  // Example usage from Dynamodb's Go SDK
  if err != nil {
    switch t := err.(type) {
    case *dynamodb.TransactionCanceledException:
        log.Fatalf("failed to write items: %s\n%v", t.Message(), t.CancellationReasons)
    default:
        log.Fatalf("failed to write items: %v", err)
    }
  }
Comments