Thuta Learning
ရှာဖွေရန်
ProjectsProgrammingbeginner

Mini Project: Task Manager (Part 2) - Methods & Error Handling

စိတ်လျှော့ပါ။ ဒီခန်းကို စာအုပ်လိုမဟုတ်ဘဲ စကားပြောသလိုပဲ၊ နားလည်လွယ်အောင် ရှင်းပါမယ်။

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Mini Project: Task Manager (Part 2) - Methods & Error Handling ကို လက်တွေ့ project ထဲမှာ အသုံးချတတ်မယ်
  • ကိုယ်တိုင် code ရေးပြီး run ကြည့်တတ်မယ်
  • Project တစ်ခုလုံးကို အဆင့်လိုက် ဆောက်တတ်မယ်

ခဏလေး ဒီလိုပဲ စဉ်းစားကြည့်

Part 1 မှာ function-based approach သုံးခဲ့ပေမယ့် Part 2 မှာတော့ Methods chapter မှာသင်ခဲ့တဲ့ receiver method pattern ကို သုံးပြီး code ပိုတည်ငြိမ်အောင် refactor လုပ်ပါမယ်။ tasks slice ကို TaskManager struct တစ်ခုရဲ့ field အဖြစ်ထည့်ပြီး Add, List, Complete, Remove တွေကို ဒီ struct ပေါ်က method အဖြစ် ပြန်ရေးပါမယ်။ Complete နဲ့ Remove ကတော့ ID မှားနေရင် ဘာဖြစ်လဲဆိုတာ ကိုင်တွယ်ရမှာမို့ Errors chapter မှာသင်ခဲ့တဲ့ error return pattern ကို လက်တွေ့ အသုံးချရပါမယ်။ ဒီအဆင့်ပြီးရင် project က struct + methods + error handling ပေါင်းစပ်ထားတဲ့ ပိုမှန်ကန်တဲ့ Go design ပုံစံဖြစ်လာပါလိမ့်မယ်။

လက်တွေ့ ဆောက်ကြည့်မယ်

TaskManager struct ကို tasks []Task field တစ်ခုတည်းနဲ့ define လုပ်ပါ။ pointer receiver (m *TaskManager) သုံးပြီး Add(title string), List(), Complete(id int) error, Remove(id int) error method လေးခုရေးပါ။ Complete နဲ့ Remove method နှစ်ခုစလုံးမှာ for loop နဲ့ ID ကို ရှာပြီး ID မတွေ့ရင် fmt.Errorf("task %d not found", id) ကို return ပြန်ပါ။ Remove မှာ slices trick (append(tasks[:i], tasks[i+1:]...)) သုံးပြီး task ကို list ထဲကနေ ဖယ်ပါ။ main() ထဲမှာ Complete/Remove ခေါ်ပြီး error ကို if err != nil နဲ့ check ပြီး print ထုတ်ပါ။

Code နမူနာ

go
package main

import "fmt"

type Task struct {
	ID    int
	Title string
	Done  bool
}

type TaskManager struct {
	tasks []Task
}

func (m *TaskManager) Add(title string) {
	t := Task{ID: len(m.tasks) + 1, Title: title}
	m.tasks = append(m.tasks, t)
}

func (m *TaskManager) List() {
	for _, t := range m.tasks {
		status := "[ ]"
		if t.Done {
			status = "[x]"
		}
		fmt.Printf("%s %d. %s\n", status, t.ID, t.Title)
	}
}

func (m *TaskManager) Complete(id int) error {
	for i := range m.tasks {
		if m.tasks[i].ID == id {
			m.tasks[i].Done = true
			return nil
		}
	}
	return fmt.Errorf("task %d not found", id)
}

func (m *TaskManager) Remove(id int) error {
	for i, t := range m.tasks {
		if t.ID == id {
			m.tasks = append(m.tasks[:i], m.tasks[i+1:]...)
			return nil
		}
	}
	return fmt.Errorf("task %d not found", id)
}

func main() {
	manager := &TaskManager{}
	manager.Add("Learn Go basics")
	manager.Add("Build task manager")

	if err := manager.Complete(1); err != nil {
		fmt.Println("Error:", err)
	}
	if err := manager.Remove(5); err != nil {
		fmt.Println("Error:", err)
	}
	manager.List()
}
You should see
Task 1 ကို complete လုပ်ပြီးတဲ့အပြင် ID 5 ကို remove လုပ်ဖို့ကြိုးစားရာမှာ "Error: task 5 not found" ဆိုပြီး print ထုတ်ပေးပါလိမ့်မယ်။

၅ မိနစ် စမ်းကြည့်

5 minutes အတွင်း Update(id int, newTitle string) error ဆိုတဲ့ method အသစ်တစ်ခု ထပ်ထည့်ပြီး task title ကို ID နဲ့ ရှာပြောင်းနိုင်အောင် ကိုယ်တိုင် implement လုပ်ကြည့်ပါ။

သတိလေးတစ်ချက်

Remove method ထဲက append(m.tasks[:i], m.tasks[i+1:]...) က slice underlying array ကို share သုံးတာဖြစ်လို့ concurrent access ရှိရင် data race ဖြစ်နိုင်တာကို သတိထားပါ။

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • TaskManager method တွေကို value receiver (m TaskManager) နဲ့ ရေးမိပြီး Add/Complete လုပ်လိုက်တာ original struct ပေါ် မထိရောက်တော့တာ - slice ကို modify ချင်ရင် pointer receiver (m *TaskManager) အမှန်ဖြစ်ရပါမယ်
  • error ကို return ပြန်ပေမယ့် main() ထဲမှာ if err != nil စစ်ဆေးဖို့ မေ့ကာ error ကို လျစ်လျူထားတတ်တာ - Go မှာ error ကို ချက်ချင်း handle လုပ်ဖို့ လိုအပ်ပါတယ်

အခု ကိုယ်တိုင် စမ်းကြည့်

5 minutes အတွင်း Update(id int, newTitle string) error ဆိုတဲ့ method အသစ်တစ်ခု ထပ်ထည့်ပြီး task title ကို ID နဲ့ ရှာပြောင်းနိုင်အောင် ကိုယ်တိုင် implement လုပ်ကြည့်ပါ။

You'll know it worked when: Task 1 ကို complete လုပ်ပြီးတဲ့အပြင် ID 5 ကို remove လုပ်ဖို့ကြိုးစားရာမှာ "Error: task 5 not found" ဆိုပြီး print ထုတ်ပေးပါလိမ့်မယ်။

Mini Project: Task Manager (Part 2) - Methods & Error Handling | Thuta Learning