refactor: common ifaces
This commit is contained in:
46
interfaces/10-stringer/_handlemethods.go
Normal file
46
interfaces/10-stringer/_handlemethods.go
Normal 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()
|
||||
*/
|
33
interfaces/10-stringer/list.go
Normal file
33
interfaces/10-stringer/list.go
Normal 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)
|
||||
}
|
||||
}
|
32
interfaces/10-stringer/main.go
Normal file
32
interfaces/10-stringer/main.go
Normal 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)
|
||||
}
|
16
interfaces/10-stringer/money.go
Normal file
16
interfaces/10-stringer/money.go
Normal 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)
|
||||
}
|
26
interfaces/10-stringer/product.go
Normal file
26
interfaces/10-stringer/product.go
Normal 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)
|
||||
}
|
43
interfaces/10-stringer/timestamp.go
Normal file
43
interfaces/10-stringer/timestamp.go
Normal 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
|
||||
}
|
Reference in New Issue
Block a user