diff --git a/interfaces/06-empty-interface/book.go b/interfaces/06-empty-interface/book.go new file mode 100644 index 0000000..d3c3c6b --- /dev/null +++ b/interfaces/06-empty-interface/book.go @@ -0,0 +1,47 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "strconv" + "time" +) + +type book struct { + title string + price money + published interface{} +} + +func (b book) print() { + p := format(b.published) + fmt.Printf("%-15s: %s - (%v)\n", b.title, b.price.string(), p) +} + +func format(v interface{}) string { + // book{title: "hobbit", price: 25}, + if v == nil { + return "unknown" + } + + var t int + + // book{title: "moby dick", price: 10, published: 118281600}, + if v, ok := v.(int); ok { + t = v + } + + // book{title: "odyssey", price: 15, published: "733622400"}, + if v, ok := v.(string); ok { + t, _ = strconv.Atoi(v) + } + + u := time.Unix(int64(t), 0) + return u.String() +} diff --git a/interfaces/06-empty-interface/empty/main.go b/interfaces/06-empty-interface/empty/main.go new file mode 100644 index 0000000..e041ec6 --- /dev/null +++ b/interfaces/06-empty-interface/empty/main.go @@ -0,0 +1,29 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +func main() { + // Let's create a variable using the empty interface type. + var any interface{} + + // The variable can accept any type of value. + any = []int{1, 2, 3} + any = map[int]bool{1: true, 2: false} + any = "hello" + any = 3 + + // You can't multiply the last number. + // Reason: `any` is an `interface{}`, it's not a number. + // any = any * 2 + // any = int(any) * 2 + + any = any.(int) * 2 + fmt.Println(any) +} diff --git a/interfaces/06-empty-interface/empty2/main.go b/interfaces/06-empty-interface/empty2/main.go new file mode 100644 index 0000000..0f11ae7 --- /dev/null +++ b/interfaces/06-empty-interface/empty2/main.go @@ -0,0 +1,43 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +func main() { + nums := []int{1, 2, 3} + + // Store a slice in `any` + var any interface{} + any = nums + + // `any` is an empty interface value, it's not a slice. + // You cannot get its length. It has no length. + // _ = len(any) + + // When you extract the slice from it, you can get the slice's length. + _ = len(any.([]int)) + + // You cannot assign an `[]T` slice to `[]interface{}` slice. + // Where `T` can be of any type. + // Reason: `[]interface{}` is a slice, it's not an `empty interface` value. + var many []interface{} + // many = nums + + // The same reason that you can't assign an `[]int` to a `[]string`. + // var words []string = nums + + // You need to copy the elements from `nums` to `many` manually. + for _, n := range nums { + many = append(many, n) + } + fmt.Println(many) + + // Each element of the `many` slice is an `empty interface` value. + // el := many[0] +} diff --git a/interfaces/06-type-switch/game.go b/interfaces/06-empty-interface/game.go similarity index 100% rename from interfaces/06-type-switch/game.go rename to interfaces/06-empty-interface/game.go diff --git a/interfaces/06-empty-interface/list.go b/interfaces/06-empty-interface/list.go new file mode 100644 index 0000000..ad574c3 --- /dev/null +++ b/interfaces/06-empty-interface/list.go @@ -0,0 +1,39 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +type printer interface { + print() +} + +type list []printer + +func (l list) print() { + if len(l) == 0 { + fmt.Println("Sorry. Our store is closed. We're waiting for the delivery 🚚.") + return + } + + for _, it := range l { + it.print() + } +} + +func (l list) discount(ratio float64) { + type discounter interface { + discount(float64) + } + + for _, it := range l { + if it, ok := it.(discounter); ok { + it.discount(ratio) + } + } +} diff --git a/interfaces/06-empty-interface/main.go b/interfaces/06-empty-interface/main.go new file mode 100644 index 0000000..aadb730 --- /dev/null +++ b/interfaces/06-empty-interface/main.go @@ -0,0 +1,23 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +func main() { + store := list{ + book{title: "moby dick", price: 10, published: 118281600}, + book{title: "odyssey", price: 15, published: "733622400"}, + book{title: "hobbit", price: 25}, + puzzle{title: "rubik's cube", price: 5}, + &game{title: "minecraft", price: 20}, + &game{title: "tetris", price: 5}, + &toy{title: "yoda", price: 150}, + } + + store.discount(.5) + store.print() +} diff --git a/interfaces/06-type-switch/money.go b/interfaces/06-empty-interface/money.go similarity index 100% rename from interfaces/06-type-switch/money.go rename to interfaces/06-empty-interface/money.go diff --git a/interfaces/06-type-switch/puzzle.go b/interfaces/06-empty-interface/puzzle.go similarity index 100% rename from interfaces/06-type-switch/puzzle.go rename to interfaces/06-empty-interface/puzzle.go diff --git a/interfaces/06-type-switch/toy.go b/interfaces/06-empty-interface/toy.go similarity index 100% rename from interfaces/06-type-switch/toy.go rename to interfaces/06-empty-interface/toy.go diff --git a/interfaces/06-type-switch/list.go b/interfaces/06-type-switch/list.go deleted file mode 100644 index 5743b60..0000000 --- a/interfaces/06-type-switch/list.go +++ /dev/null @@ -1,96 +0,0 @@ -// For more tutorials: https://blog.learngoprogramming.com -// -// Copyright © 2018 Inanc Gumus -// Learn Go Programming Course -// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ -// - -package main - -import "fmt" - -type printer interface { - print() - // discount(ratio float64) -} - -type list []printer - -func (l list) print() { - if len(l) == 0 { - fmt.Println("Sorry. Our store is closed. We're waiting for the delivery 🚚.") - return - } - - for _, it := range l { - it.print() - } -} - -// -// type switch can find the type behind an interface value. -// -func (l list) discount(ratio float64) { - type discounter interface { - discount(float64) - } - - for _, it := range l { - if it, ok := it.(discounter); ok { - it.discount(ratio) - } - } -} - -// ---- - -// -// type assertion can pull out the real value behind an interface value. -// -// it can also check whether the value convertable to a given type. -// -// func (l list) discount(ratio float64) { -// for _, it := range l { -// g, ok := it.(interface{ discount(float64) }) -// if !ok { -// continue -// } - -// g.discount(ratio) -// } -// } - -// ---- - -// -// type switch can pull out the real value behind an interface value. -// -// func (l list) discount(ratio float64) { -// for _, it := range l { -// switch it := it.(type) { -// case *game: -// it.discount(ratio) -// case *puzzle: -// it.discount(ratio) -// } -// } -// } - -// ---- - -// -// type switch can find the type behind an interface value. -// -// func (l list) discount(ratio float64) { -// for _, it := range l { -// switch it.(type) { -// case *game: -// fmt.Print("it's a *game! --> ") -// case *puzzle: -// fmt.Print("it's a *puzzle! --> ") -// default: -// fmt.Print("neither --> ") -// } -// it.print() -// } -// } diff --git a/interfaces/06-type-switch/main.go b/interfaces/06-type-switch/main.go deleted file mode 100644 index 9eeafad..0000000 --- a/interfaces/06-type-switch/main.go +++ /dev/null @@ -1,31 +0,0 @@ -// For more tutorials: https://blog.learngoprogramming.com -// -// Copyright © 2018 Inanc Gumus -// Learn Go Programming Course -// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ -// - -package main - -func main() { - var ( - mobydick = book{title: "moby dick", price: 10} - minecraft = game{title: "minecraft", price: 20} - tetris = game{title: "tetris", price: 5} - rubik = puzzle{title: "rubik's cube", price: 5} - yoda = toy{title: "yoda", price: 150} - ) - - var store list - store = append(store, &minecraft, &tetris, mobydick, rubik, &yoda) - - // #2 - store.discount(.5) - store.print() - - // #1 - // var p printer - // p = &tetris - // tetris.discount(.5) - // p.print() -} diff --git a/interfaces/07-type-switch/book.go b/interfaces/07-type-switch/book.go new file mode 100644 index 0000000..81ca4f1 --- /dev/null +++ b/interfaces/07-type-switch/book.go @@ -0,0 +1,47 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import ( + "fmt" + "strconv" + "time" +) + +type book struct { + title string + price money + published interface{} +} + +func (b book) print() { + p := format(b.published) + fmt.Printf("%-15s: %s - (%v)\n", b.title, b.price.string(), p) +} + +func format(v interface{}) string { + var t int + + switch v := v.(type) { + case int: + // book{title: "moby dick", price: 10, published: 118281600}, + t = v + case string: + // book{title: "odyssey", price: 15, published: "733622400"}, + t, _ = strconv.Atoi(v) + default: + // book{title: "hobbit", price: 25}, + return "unknown" + } + + // Mon Jan 2 15:04:05 -0700 MST 2006 + const layout = "2006/01" + + u := time.Unix(int64(t), 0) + return u.Format(layout) +} diff --git a/interfaces/07-type-switch/game.go b/interfaces/07-type-switch/game.go new file mode 100644 index 0000000..b51bf39 --- /dev/null +++ b/interfaces/07-type-switch/game.go @@ -0,0 +1,23 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +type game struct { + title string + price money +} + +func (g *game) print() { + fmt.Printf("%-15s: %s\n", g.title, g.price.string()) +} + +func (g *game) discount(ratio float64) { + g.price *= money(1 - ratio) +} diff --git a/interfaces/07-type-switch/list.go b/interfaces/07-type-switch/list.go new file mode 100644 index 0000000..ad574c3 --- /dev/null +++ b/interfaces/07-type-switch/list.go @@ -0,0 +1,39 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +type printer interface { + print() +} + +type list []printer + +func (l list) print() { + if len(l) == 0 { + fmt.Println("Sorry. Our store is closed. We're waiting for the delivery 🚚.") + return + } + + for _, it := range l { + it.print() + } +} + +func (l list) discount(ratio float64) { + type discounter interface { + discount(float64) + } + + for _, it := range l { + if it, ok := it.(discounter); ok { + it.discount(ratio) + } + } +} diff --git a/interfaces/07-type-switch/main.go b/interfaces/07-type-switch/main.go new file mode 100644 index 0000000..aadb730 --- /dev/null +++ b/interfaces/07-type-switch/main.go @@ -0,0 +1,23 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +func main() { + store := list{ + book{title: "moby dick", price: 10, published: 118281600}, + book{title: "odyssey", price: 15, published: "733622400"}, + book{title: "hobbit", price: 25}, + puzzle{title: "rubik's cube", price: 5}, + &game{title: "minecraft", price: 20}, + &game{title: "tetris", price: 5}, + &toy{title: "yoda", price: 150}, + } + + store.discount(.5) + store.print() +} diff --git a/interfaces/07-composition/money.go b/interfaces/07-type-switch/money.go similarity index 100% rename from interfaces/07-composition/money.go rename to interfaces/07-type-switch/money.go diff --git a/interfaces/06-type-switch/book.go b/interfaces/07-type-switch/puzzle.go similarity index 71% rename from interfaces/06-type-switch/book.go rename to interfaces/07-type-switch/puzzle.go index 9b0ebaa..5ea12b9 100644 --- a/interfaces/06-type-switch/book.go +++ b/interfaces/07-type-switch/puzzle.go @@ -9,11 +9,11 @@ package main import "fmt" -type book struct { +type puzzle struct { title string price money } -func (b book) print() { - fmt.Printf("%-15s: %s\n", b.title, b.price.string()) +func (p puzzle) print() { + fmt.Printf("%-15s: %s\n", p.title, p.price.string()) } diff --git a/interfaces/07-type-switch/toy.go b/interfaces/07-type-switch/toy.go new file mode 100644 index 0000000..9467e69 --- /dev/null +++ b/interfaces/07-type-switch/toy.go @@ -0,0 +1,23 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +type toy struct { + title string + price money +} + +func (t *toy) print() { + fmt.Printf("%-15s: %s\n", t.title, t.price.string()) +} + +func (t *toy) discount(ratio float64) { + t.price *= money(1 - ratio) +} diff --git a/interfaces/07-composition/book.go b/interfaces/08-composition/book.go similarity index 100% rename from interfaces/07-composition/book.go rename to interfaces/08-composition/book.go diff --git a/interfaces/07-composition/discount.go b/interfaces/08-composition/discount.go similarity index 100% rename from interfaces/07-composition/discount.go rename to interfaces/08-composition/discount.go diff --git a/interfaces/07-composition/game.go b/interfaces/08-composition/game.go similarity index 100% rename from interfaces/07-composition/game.go rename to interfaces/08-composition/game.go diff --git a/interfaces/07-composition/list.go b/interfaces/08-composition/list.go similarity index 100% rename from interfaces/07-composition/list.go rename to interfaces/08-composition/list.go diff --git a/interfaces/07-composition/main.go b/interfaces/08-composition/main.go similarity index 100% rename from interfaces/07-composition/main.go rename to interfaces/08-composition/main.go diff --git a/interfaces/08-composition/money.go b/interfaces/08-composition/money.go new file mode 100644 index 0000000..86f7d63 --- /dev/null +++ b/interfaces/08-composition/money.go @@ -0,0 +1,16 @@ +// For more tutorials: https://blog.learngoprogramming.com +// +// Copyright © 2018 Inanc Gumus +// Learn Go Programming Course +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ +// + +package main + +import "fmt" + +type money float64 + +func (m money) string() string { + return fmt.Sprintf("$%.2f", m) +} diff --git a/interfaces/07-composition/puzzle.go b/interfaces/08-composition/puzzle.go similarity index 100% rename from interfaces/07-composition/puzzle.go rename to interfaces/08-composition/puzzle.go diff --git a/interfaces/07-composition/time.go b/interfaces/08-composition/time.go similarity index 100% rename from interfaces/07-composition/time.go rename to interfaces/08-composition/time.go diff --git a/interfaces/07-composition/types.go b/interfaces/08-composition/types.go similarity index 100% rename from interfaces/07-composition/types.go rename to interfaces/08-composition/types.go