กระรอกดินต้นฉบับค่อย ๆ ดึงแถบกระดาษที่แบ่งเป็นท่อนโดยเก็บหมุดคั่นไว้ปลายแต่ละท่อน

Go strings.SplitAfterSeq: แบ่งข้อความแบบ iterator โดยเก็บตัวคั่นไว้

พี่โชว์Engineering

ถ้าต้องแยก log ก้อนใหญ่แล้วใช้เพียงไม่กี่ record การเรียก strings.SplitAfter จะสร้าง slice ที่ถือทุกส่วนไว้พร้อมกันครับ strings.SplitAfterSeq คืน iter.Seq[string] ให้ consumer รับทีละส่วน และยังเก็บ separator ไว้ท้ายส่วนเหมือน SplitAfter

WHY: ดึงทีละใบ แทนเทเอกสารทั้งกล่อง

ลองนึกถึงม้วนใบเสร็จที่มีเส้นปรุ เราอาจฉีกทีละใบจนพบรายการที่ต้องการ ไม่จำเป็นต้องฉีกทั้งม้วนแล้ววางเต็มโต๊ะ Iterator ช่วยลด slice ของผลลัพธ์และเปิดทางให้หยุดเร็ว แต่ substring ที่ได้ยังอ้างข้อมูลจาก string ต้นฉบับ จึงไม่ได้แปลว่าหน่วยความจำของ input ใหญ่จะถูกปล่อยทันที

package main

import (
	"slices"
	"strings"
	"testing"
)

func firstTwoRecords(input string) []string {
	parts := make([]string, 0, 2)
	for part := range strings.SplitAfterSeq(input, "\n") {
		parts = append(parts, part)
		if len(parts) == 2 {
			break
		}
	}
	return parts
}

func TestSplitAfterSeq(t *testing.T) {
	got := firstTwoRecords("alpha\nbeta\ngamma\n")
	if !slices.Equal(got, []string{"alpha\n", "beta\n"}) {
		t.Fatalf("unexpected records: %#v", got)
	}
	all := slices.Collect(strings.SplitAfterSeq("ab", ""))
	if !slices.Equal(all, []string{"a", "b"}) {
		t.Fatalf("empty separator must split after UTF-8 sequences: %#v", all)
	}
}

ขอบเขตที่ต้องรู้

Iterator เป็น single-use: อย่าเก็บไว้แล้วหวังวนซ้ำเหมือน slice หากต้องใช้หลายรอบให้สร้าง SplitAfterSeq ใหม่ หรือ slices.Collect เมื่อข้อมูลเล็กและต้อง random access จริง ๆ ส่วน separator ว่างจะแบ่งหลัง UTF-8 sequence แต่ละตัว ไม่ใช่หลังทุก byte

ถ้าต้องเก็บผลลัพธ์เล็กไว้นานกว่าข้อความต้นฉบับก้อนใหญ่มาก ให้พิจารณา strings.Clone(part) ตรง boundary เพื่อตัด ownership ให้ชัด อย่า clone ทุกชิ้นโดยอัตโนมัติ เพราะจะลบประโยชน์ด้าน allocation ไปเอง

Recap

  • ใช้ SplitAfterSeq เมื่ออ่านตามลำดับและอาจหยุดก่อนจบ
  • ใช้ SplitSeq หากไม่ต้องเก็บตัวคั่น
  • จำว่า iterator ใช้ครั้งเดียวและ substring ยังผูกกับ input
  • collect หรือ clone เฉพาะเมื่อ ownership และการเข้าถึงต้องการจริง