refactor: common ifaces

This commit is contained in:
Inanc Gumus
2019-10-17 14:11:51 +03:00
parent 34cf7f7de2
commit c062a46355
119 changed files with 1247 additions and 194 deletions

View File

@ -0,0 +1,46 @@
// 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/
//
// In the depths of the Go standard library's fmt package...
// Printing functions use the handleMethods method.
// Example:
// var pocket money = 10
// fmt.Println(pocket)
// the argument can be any type of value
// stores the pocket variable in the argument variable
// ^
// |
func (p *pp) handleMethods(argument interface{}) (handled bool) {
// ...
// Checks whether a given argument is an error or an fmt.Stringer
switch v := argument.(type) {
// ...
// If the argument is a Stringer, calls its String() method
case Stringer:
// ...
// pocket.String()
// ^
// |
p.fmtString(v.String(), verb)
return
}
// ...
}
/*
The original `handleMethods` code is more involved:
https://github.com/golang/go/blob/6f51082da77a1d4cafd5b7af0db69293943f4066/src/fmt/print.go#L574
-> 574#handleMethods(..)
-> 627#Stringer type check: If `v` is a Stringer, run:
-> 630#v.String()
*/

View File

@ -0,0 +1,33 @@
// 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"
"strings"
)
type list []*product
func (l list) String() string {
if len(l) == 0 {
return "Sorry. We're waiting for delivery 🚚.\n"
}
var str strings.Builder
for _, p := range l {
fmt.Fprintf(&str, "* %s\n", p)
}
return str.String()
}
func (l list) discount(ratio float64) {
for _, p := range l {
p.discount(ratio)
}
}

View File

@ -0,0 +1,32 @@
// 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() {
// The money type is a stringer.
// You don't need to call the String method when printing a value of it.
// var pocket money = 10
// fmt.Println(pocket)
l := list{
{title: "moby dick", price: 10, released: toTimestamp(118281600)},
{title: "odyssey", price: 15, released: toTimestamp("733622400")},
{title: "hobbit", price: 25},
}
// The list is a stringer.
// The `fmt.Print` function can print the `l`
// by calling `l`'s `String()` method.
//
// Underneath, `fmt.Print` uses a type switch to
// detect whether a type is a Stringer:
// https://golang.org/src/fmt/print.go#L627
fmt.Print(l)
}

View File

@ -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)
}

View File

@ -0,0 +1,26 @@
// 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 product struct {
title string
price money
released timestamp
}
func (p *product) String() string {
return fmt.Sprintf("%s: %s (%s)", p.title, p.price, p.released)
}
func (p *product) discount(ratio float64) {
p.price *= money(1 - ratio)
}

View File

@ -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 (
"strconv"
"time"
)
// timestamp stores, formats and automatically prints a timestamp: it's a stringer.
type timestamp struct {
time.Time
}
// String method makes the timestamp an fmt.stringer.
func (ts timestamp) String() string {
if ts.IsZero() {
return "unknown"
}
// Mon Jan 2 15:04:05 -0700 MST 2006
const layout = "2006/01"
return ts.Format(layout)
}
func toTimestamp(v interface{}) (ts timestamp) {
var t int
switch v := v.(type) {
case int:
t = v
case string:
t, _ = strconv.Atoi(v)
}
ts.Time = time.Unix(int64(t), 0)
return ts
}