タスクの完了
CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 23/68。
チャレンジ
簡単タスク管理システムのこのパートでは、タスクを完了としてマークする機能を実装します。このチャレンジでは、ポインタレシーバを使用して元のタスクデータを変更することに焦点を当て、ポインタによって構造体のフィールドを永続的に更新する方法を学びます。
重要な注意点: タスク名にはスペースが含まれる可能性があるため(例:「Buy groceries」)、入力行全体を読み取るために bufio.Scanner を使用する必要があります。fmt.Scanf 関数は最初のスペースで読み取りを停止するため、スペースを含むタスク名が正しく読み取れません。bufio.NewScanner(os.Stdin) を使用し、scanner.Scan() に続いて scanner.Text() を呼び出すことで、完全な行を読み取ってください。
3つの入力を受け取ります:
- タスクの数を示す文字列(例:
"4") - タスクデータを含む文字列。形式は
"name1:status1,name2:status2,name3:status3"で、ステータスは"true"または"false"です(例:"Buy groceries:false,Call dentist:true,Finish project:false,Review code:false") - 完了させるタスクのインデックスを示す文字列(例:3番目のタスクの場合は
"2"、0ベースのインデックスを使用)
あなたのタスクは以下の通りです:
- 以前のチャレンジと同じ、
Name(string) とCompleted(bool) フィールドを持つTask構造体を定義します Task構造体のスライスへのポインタとインデックス (int) をパラメータとして受け取るcompleteTaskという関数を作成しますcompleteTask関数内で、指定されたインデックスにあるタスクのCompletedフィールドをtrueに変更しますbufio.Scannerを使用して入力行を適切に読み取ります:- スキャナーを作成します:
scanner := bufio.NewScanner(os.Stdin) - 各入力行に対して:
scanner.Scan()を呼び出し、次にscanner.Text()を呼び出します - これにより、スペースを含むタスク名が正しく読み取られるようになります
- スキャナーを作成します:
- 2番目の入力からタスクデータを解析して、タスクのスライスを作成します:
- 入力をカンマで分割して、個々のタスクエントリを取得します
- 各エントリをコロンで分割して、名前とステータスを分離します
- ステータス文字列をブール値に変換します(
"true"はtrueに、"false"はfalseになります)
- 3番目の入力文字列を整数に変換して、タスクのインデックスを取得します
- スライスへのポインタとインデックスを指定して
completeTask関数を呼び出します - タスクを完了させた後、前のチャレンジと同じ形式ですべてのタスクを表示します:
- 完了したタスクの場合:
"[x] [task_name]" - 未完了のタスクの場合:
"[ ] [task_name]"
- 完了したタスクの場合:
- 確認メッセージを出力します:
"Task '[task_name]' marked as completed!" - 更新されたサマリーを出力します:
"Total: [total_count] tasks ([completed_count] completed, [incomplete_count] remaining)"
インデックス文字列を整数に変換するには strconv パッケージを使用してください。このチャレンジは、ポインタレシーバによって元のデータ構造を変更し、関数が終了した後もタスクリストへの永続的な変更を維持する方法を示しています。
自分で試してみよう
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type Task struct {
Name string
Completed bool
}
func viewAllTasks(tasks []Task) {
for _, task := range tasks {
if task.Completed {
fmt.Printf("[x] %s\n", task.Name)
} else {
fmt.Printf("[ ] %s\n", task.Name)
}
}
}
func main() {
var numTasksStr string
fmt.Scanln(&numTasksStr)
numTasks, _ := strconv.Atoi(numTasksStr)
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
taskData := scanner.Text()
var tasks []Task
taskEntries := strings.Split(taskData, ",")
for _, entry := range taskEntries {
parts := strings.Split(entry, ":")
if len(parts) >= 2 {
name := parts[0]
completed, _ := strconv.ParseBool(parts[1])
task := Task{
Name: name,
Completed: completed,
}
tasks = append(tasks, task)
}
}
viewAllTasks(tasks)
completedCount := 0
for _, task := range tasks {
if task.Completed {
completedCount++
}
}
incompleteCount := numTasks - completedCount
fmt.Printf("Total: %d tasks (%d completed, %d remaining)\n", numTasks, completedCount, incompleteCount)
}