diff --git a/interfaces/04-interfaces/puzzle.go b/interfaces/04-interfaces/puzzle.go index 5ea12b9..e839e54 100644 --- a/interfaces/04-interfaces/puzzle.go +++ b/interfaces/04-interfaces/puzzle.go @@ -14,6 +14,8 @@ type puzzle struct { price money } +// if you remove this method, +// you can no longer add it to the `store` in `main()`. func (p puzzle) print() { fmt.Printf("%-15s: %s\n", p.title, p.price.string()) } diff --git a/interfaces/05-assertion/book.go b/interfaces/05-assertion/book.go index a55520f..9b0ebaa 100644 --- a/interfaces/05-assertion/book.go +++ b/interfaces/05-assertion/book.go @@ -10,9 +10,8 @@ package main import "fmt" type book struct { - title string - price money - readTime int + title string + price money } func (b book) print() { diff --git a/interfaces/05-assertion/game.go b/interfaces/05-assertion/game.go index 2705bee..b51bf39 100644 --- a/interfaces/05-assertion/game.go +++ b/interfaces/05-assertion/game.go @@ -10,9 +10,8 @@ package main import "fmt" type game struct { - title string - price money - playTime int + title string + price money } func (g *game) print() { diff --git a/interfaces/05-assertion/list.go b/interfaces/05-assertion/list.go index 8a3cbf7..ad73fe9 100644 --- a/interfaces/05-assertion/list.go +++ b/interfaces/05-assertion/list.go @@ -11,6 +11,9 @@ import "fmt" type printer interface { print() + + // use type assertion when you cannot change the interface. + // discount(ratio float64) } type list []printer @@ -26,59 +29,50 @@ func (l list) print() { } } +// type assertion can extract the wrapped value. +// or: it can put the value into another interface. func (l list) discount(ratio float64) { + // you can declare an interface in a function/method as well. + // interface is just a type. type discounter interface { discount(float64) } for _, it := range l { + // you can assert to an interface. + // and extract another interface. 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 { -// // remember: interface is a type -// if it, ok := it.(interface{ discount(float64) }); ok { -// it.discount(ratio) +// // you can inline-assert interfaces +// // interface is just a type. +// 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. -// +// // 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 { -// switch it.(type) { -// case *game: -// fmt.Print("it's a *game! --> ") -// case *puzzle: -// fmt.Print("it's a *puzzle! --> ") -// default: -// fmt.Print("neither --> ") +// g, ok := it.(*game) +// if !ok { +// continue // } -// it.print() + +// g.discount(ratio) // } // } diff --git a/interfaces/05-assertion/main.go b/interfaces/05-assertion/main.go index bde7e9c..9eeafad 100644 --- a/interfaces/05-assertion/main.go +++ b/interfaces/05-assertion/main.go @@ -13,16 +13,19 @@ func main() { 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) + store = append(store, &minecraft, &tetris, mobydick, rubik, &yoda) + // #2 store.discount(.5) store.print() - // minecraft.discount(.5) - // minecraft.print() + // #1 + // var p printer + // p = &tetris + // tetris.discount(.5) + // p.print() } - -// store.discount() diff --git a/interfaces/05-assertion/puzzle.go b/interfaces/05-assertion/puzzle.go index de54585..5ea12b9 100644 --- a/interfaces/05-assertion/puzzle.go +++ b/interfaces/05-assertion/puzzle.go @@ -14,10 +14,6 @@ type puzzle struct { price money } -func (p *puzzle) print() { +func (p puzzle) print() { fmt.Printf("%-15s: %s\n", p.title, p.price.string()) } - -func (p *puzzle) discount(ratio float64) { - p.price *= money(1 - ratio) -} diff --git a/interfaces/05-assertion/toy.go b/interfaces/05-assertion/toy.go new file mode 100644 index 0000000..9467e69 --- /dev/null +++ b/interfaces/05-assertion/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/06-type-switch/book.go b/interfaces/06-type-switch/book.go new file mode 100644 index 0000000..9b0ebaa --- /dev/null +++ b/interfaces/06-type-switch/book.go @@ -0,0 +1,19 @@ +// 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 book struct { + title string + price money +} + +func (b book) print() { + fmt.Printf("%-15s: %s\n", b.title, b.price.string()) +} diff --git a/interfaces/06-type-switch/game.go b/interfaces/06-type-switch/game.go new file mode 100644 index 0000000..b51bf39 --- /dev/null +++ b/interfaces/06-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/06-type-switch/list.go b/interfaces/06-type-switch/list.go new file mode 100644 index 0000000..5743b60 --- /dev/null +++ b/interfaces/06-type-switch/list.go @@ -0,0 +1,96 @@ +// 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 new file mode 100644 index 0000000..9eeafad --- /dev/null +++ b/interfaces/06-type-switch/main.go @@ -0,0 +1,31 @@ +// 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/06-composition/money.go b/interfaces/06-type-switch/money.go similarity index 100% rename from interfaces/06-composition/money.go rename to interfaces/06-type-switch/money.go diff --git a/interfaces/06-type-switch/puzzle.go b/interfaces/06-type-switch/puzzle.go new file mode 100644 index 0000000..5ea12b9 --- /dev/null +++ b/interfaces/06-type-switch/puzzle.go @@ -0,0 +1,19 @@ +// 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 puzzle struct { + title string + price money +} + +func (p puzzle) print() { + fmt.Printf("%-15s: %s\n", p.title, p.price.string()) +} diff --git a/interfaces/06-type-switch/toy.go b/interfaces/06-type-switch/toy.go new file mode 100644 index 0000000..9467e69 --- /dev/null +++ b/interfaces/06-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/06-composition/book.go b/interfaces/07-composition/book.go similarity index 100% rename from interfaces/06-composition/book.go rename to interfaces/07-composition/book.go diff --git a/interfaces/06-composition/discount.go b/interfaces/07-composition/discount.go similarity index 100% rename from interfaces/06-composition/discount.go rename to interfaces/07-composition/discount.go diff --git a/interfaces/06-composition/game.go b/interfaces/07-composition/game.go similarity index 100% rename from interfaces/06-composition/game.go rename to interfaces/07-composition/game.go diff --git a/interfaces/06-composition/list.go b/interfaces/07-composition/list.go similarity index 100% rename from interfaces/06-composition/list.go rename to interfaces/07-composition/list.go diff --git a/interfaces/06-composition/main.go b/interfaces/07-composition/main.go similarity index 100% rename from interfaces/06-composition/main.go rename to interfaces/07-composition/main.go diff --git a/interfaces/07-composition/money.go b/interfaces/07-composition/money.go new file mode 100644 index 0000000..86f7d63 --- /dev/null +++ b/interfaces/07-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/06-composition/puzzle.go b/interfaces/07-composition/puzzle.go similarity index 100% rename from interfaces/06-composition/puzzle.go rename to interfaces/07-composition/puzzle.go diff --git a/interfaces/06-composition/time.go b/interfaces/07-composition/time.go similarity index 100% rename from interfaces/06-composition/time.go rename to interfaces/07-composition/time.go diff --git a/interfaces/06-composition/types.go b/interfaces/07-composition/types.go similarity index 100% rename from interfaces/06-composition/types.go rename to interfaces/07-composition/types.go