Slide 1

Slide 1 text

printf - args num ok? Umeda.go #3 2018 - 02 - 24 @decafe09

Slide 2

Slide 2 text

fmt.Printf fmt.Printf("%s", "moji")

Slide 3

Slide 3 text

fmt.Printf fmt.Printf("%s", "moji", "yobun")  

Slide 4

Slide 4 text

fmt.Printf $ go build # ここでは気づけない $ go run main.go # ここで気づける moji%!(EXTRA string=yobun)

Slide 5

Slide 5 text

fmt.Printf $ go build # ここでは気づけない $ go run main.go # ここで気づける moji%!(EXTRA string=yobun) func main() { http.HandleFunc( "/xxx", func(w http.ResponseWriter, r *http.Request) { fmt.Printf("%s", "moji", "yobun") return }, ) http.ListenAndServe(":8080", nil) }

Slide 6

Slide 6 text

fmt.Printf $ go build # ここでは気づけない $ go run main.go # ここでは気づけない $ curl localhost:8080/xxx # ここで気づける moji%!(EXTRA string=yobun)

Slide 7

Slide 7 text

go vet $ go vet ./main.go:6: Printf call needs 1 arg but has 2 args go vet ! curl     " go vet CI  go vet

Slide 8

Slide 8 text

go vet –printfuncs $ go vet –printfuncs=Infof ./main.go:6: Infof call needs 1 arg but has 2 args func Infof(format string, a ...interface{}) (n int, err error) { return fmt.Printf(format, a...) }

Slide 9

Slide 9 text

go vet @ Go 1.10 $ go test ./main.go:6: Printf call needs 1 arg but has 2 args   go1.9.3 main.go:6: wrong number of args for format in Printf call: 1 needed but 2 args go1.10 main.go:6: Printf call needs 1 arg but has 2 args go test go vet   go test -printfuncs  

Slide 10

Slide 10 text

Humm... format := "%s" fmt.Printf(format, "moji", ”yobun")

Slide 11

Slide 11 text

Humm... $ go build # ここでは気づけない $ go vet # ここでは気づけない $ go run main.go # ここで気づける moji%!(EXTRA string=yobun) http ! %  #  &$"%  

Slide 12

Slide 12 text

Background API6=3.;?>/2,BW!:20/)O   APIVK" C %!8>?4+?5JSAPIRFP XXNTL@YYNTLIEH  XXYYEH  XX, YY O(&'!format!O(& %D 71? +<:20/GQ&72-/M%A format#xx,yy*9=-.;?U$ 

Slide 13

Slide 13 text

Thinking... "0(' !  0(',1#%$ /0( $   !  +.)*format !format  !&-...

Slide 14

Slide 14 text

Result func check(format string) error 1. format %! 2. format message 3. format %! 4. %!      func main() { format := "%s" err := check(format) if err != nil { panic(err) } fmt.Println(message(format)) } func message(format string) string { return fmt.Sprintf(format, "moji", "yobun") } func check(format string) error { pre := strings.Count(format, "%!") msg := message(format) post := strings.Count(msg, "%!") if post > pre { return errors.New("format error: " + msg) } return nil }

Slide 15

Slide 15 text

OK All errors begin with the string "%!" followed sometimes by a single character (the verb) and end with a parenthesized description. https://golang.org/pkg/fmt/

Slide 16

Slide 16 text

Check $ go run main.go panic: format error: moji%!(EXTRA string=yobun)

Slide 17

Slide 17 text

Profile   decafe09      

Slide 18

Slide 18 text