fmt, strings และ strconv
fmt — Formatted I/O
หัวข้อที่มีชื่อว่า “fmt — Formatted I/O”Package fmt คือจุดเริ่มต้นของ output เกือบทั้งหมดใน Go มีสามฟังก์ชันหลักที่ครอบคลุมกรณีการใช้งานส่วนใหญ่:
fmt.Println(args...)— พิมพ์แต่ละ argument คั่นด้วยช่องว่าง แล้วขึ้นบรรทัดใหม่fmt.Printf(format, args...)— พิมพ์โดยใช้ format string ที่มี verbfmt.Sprintf(format, args...)— คืนค่า string ที่ฟอร์แมตแล้วแทนที่จะพิมพ์
Format verbs
หัวข้อที่มีชื่อว่า “Format verbs”| Verb | ความหมาย |
|---|---|
%v | การแสดงผลแบบ default |
%+v | Struct พร้อมชื่อ field |
%#v | การแสดงผลแบบ Go syntax |
%T | Type ของค่า |
%d | เลขฐานสิบ (decimal integer) |
%s | String (ไม่มีเครื่องหมายคำพูด) |
%q | String ในเครื่องหมายคำพูดคู่พร้อม Go escaping |
%f | ทศนิยม (floating-point decimal) |
type Person struct { Name string; Age int }p := Person{"Alice", 30}fmt.Printf("%v\n", p) // {Alice 30}fmt.Printf("%+v\n", p) // {Name:Alice Age:30}fmt.Printf("%#v\n", p) // main.Person{Name:"Alice", Age:30}fmt.Printf("%T\n", p) // main.Personstrings — การจัดการข้อความ
หัวข้อที่มีชื่อว่า “strings — การจัดการข้อความ”Package strings ให้บริการฟังก์ชันสำหรับการค้นหา แยก รวม และแปลง string ใน Go นั้น string เป็น immutable UTF-8 byte sequence ดังนั้นฟังก์ชันเหล่านี้จะคืนค่า string ใหม่แทนที่จะแก้ไข in-place
s := "hello, world"strings.Contains(s, "world") // truestrings.HasPrefix(s, "hello") // truestrings.Split(s, ", ") // ["hello" "world"]strings.Join([]string{"a","b"}, "-") // "a-b"strings.ReplaceAll(s, "l", "L") // "heLLo, worLd"strings.ToUpper(s) // "HELLO, WORLD"strings.TrimSpace(" hi ") // "hi"strings.Builder — การต่อ string อย่างมีประสิทธิภาพ
หัวข้อที่มีชื่อว่า “strings.Builder — การต่อ string อย่างมีประสิทธิภาพ”เมื่อสร้าง string จากหลายส่วนในลูป ให้ใช้ strings.Builder แทน += เพราะ += จะสร้าง string ใหม่ทุกครั้งที่วนซ้ำ ส่วน Builder เขียนลงใน buffer ที่ขยายตัวได้และ allocate string สุดท้ายเพียงครั้งเดียว
var b strings.Builderfor i := 0; i < 5; i++ { fmt.Fprintf(&b, "item%d ", i)}result := strings.TrimSpace(b.String()) // "item0 item1 item2 item3 item4"strconv — การแปลงระหว่าง string และตัวเลข
หัวข้อที่มีชื่อว่า “strconv — การแปลงระหว่าง string และตัวเลข”strconv แปลงระหว่าง string และ numeric type ฟังก์ชันที่พบบ่อยที่สุด:
n, err := strconv.Atoi("42") // string → ints := strconv.Itoa(42) // int → stringf, err := strconv.ParseFloat("3.14", 64) // string → float64b, err := strconv.ParseBool("true") // string → boolAtoi และ ParseFloat คืนค่า (value, error) เพราะ input อาจไม่ใช่ตัวเลขที่ถูกต้อง ควรตรวจสอบ error ก่อนใช้ค่าเสมอ
package main
import ( "fmt" "strconv" "strings")
type Person struct { Name string Age int}
func main() { // fmt verbs p := Person{Name: "Alice", Age: 30} fmt.Printf("%v\n", p) fmt.Printf("%+v\n", p) fmt.Printf("%#v\n", p) fmt.Printf("%T\n", p) fmt.Printf("%d %s %q\n", 42, "hello", "world")
// Sprintf builds a string s := fmt.Sprintf("Name: %s, Age: %d", p.Name, p.Age) fmt.Println(s)
// strings package text := " Go is great " fmt.Println(strings.TrimSpace(text)) fmt.Println(strings.Contains(text, "great")) fmt.Println(strings.ToUpper(strings.TrimSpace(text)))
words := strings.Split("one,two,three", ",") fmt.Println(words) fmt.Println(strings.Join(words, " | ")) fmt.Println(strings.ReplaceAll("aabbcc", "b", "x"))
// strings.Builder — efficient concatenation var b strings.Builder for i := 0; i < 3; i++ { fmt.Fprintf(&b, "item%d ", i) } fmt.Println(strings.TrimSpace(b.String()))
// strconv n, err := strconv.Atoi("123") if err == nil { fmt.Println(n + 1) } fmt.Println(strconv.Itoa(456)) f, err := strconv.ParseFloat("3.14", 64) if err == nil { fmt.Printf("%.2f\n", f) }}Loading Go runtime (first run only, ~8 MB)…
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| สิ่งที่ได้ | ประโยชน์ | ต้นทุน |
|---|---|---|
| fmt.Sprintf | flexible string formatting | allocate string ใหม่ทุกครั้ง |
| fmt.Fprintf(w, …) | write to any io.Writer | ต้องระวัง error return |
| strings.Builder | efficient string concatenation | ต้อง Reset() ถ้า reuse |
| %v / %+v / %#v | inspect any value | reflect-based — ช้ากว่า explicit conversion |
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”- fmt.Println เหมาะสำหรับ production logging — ใช้ structured logger (log/slog, zap) แทนใน production — fmt ไม่รองรับ log level, structured fields, หรือ JSON output
- string concatenation ด้วย + เร็วกว่า fmt.Sprintf — ขึ้นกับจำนวน concatenation — strings.Builder เร็วที่สุดสำหรับหลาย pieces ใน loop
- %d กับ %v ต่างกันมาก — %d explicit สำหรับ integer, %v generic แต่ผลลัพธ์เหมือนกันสำหรับ int; ต่างกันสำหรับ struct
- rune กับ byte เหมือนกัน — byte คือ uint8 (1 byte), rune คือ int32 (1-4 bytes สำหรับ Unicode codepoint)
💡 ตัวอย่างจากของจริง
Kubernetes: kubectl output ใช้ fmt.Fprintf + tabwriter สำหรับ table formatting ที่ align column อัตโนมัติ
Prometheus: metric label string construction ใช้ fmt.Sprintf — เช่น
http_requests_total{method="GET",path="/api"}Go HTTP server: error response ใช้ fmt.Sprintf สร้าง message แล้วส่งผ่าน http.Error() ซึ่งรับ string