Oznaczanie zadania jako ukończonego
Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 23 z 68.
Wyzwanie
ŁatwyW tej części systemu zarządzania zadaniami zaimplementujesz możliwość oznaczania zadań jako ukończonych. To wyzwanie koncentruje się na użyciu odbiorców wskaźnikowych do modyfikowania oryginalnych danych zadania i pokazuje, jak wskaźniki pozwalają trwale aktualizować pola struktury.
Ważna uwaga: Ponieważ nazwy zadań mogą zawierać spacje (na przykład "Buy groceries"), musisz użyć bufio.Scanner, aby odczytywać całe wiersze danych wejściowych. Funkcja fmt.Scanf przestaje czytać przy pierwszej spacji, co powodowałoby błędne odczytywanie nazw zadań zawierających spacje. Użyj bufio.NewScanner(os.Stdin) i wywołaj scanner.Scan(), a następnie scanner.Text(), aby odczytać całe wiersze.
Otrzymasz trzy dane wejściowe:
- Łańcuch reprezentujący liczbę zadań (np.
"4") - Łańcuch zawierający dane zadań w formacie:
"name1:status1,name2:status2,name3:status3", gdzie status ma wartość"true"albo"false"(np."Buy groceries:false,Call dentist:true,Finish project:false,Review code:false") - Łańcuch reprezentujący indeks zadania do ukończenia (np.
"2"oznacza trzecie zadanie, przy indeksowaniu od 0)
Twoje zadanie:
- Zdefiniuj taką samą strukturę
Taskjak w poprzednich wyzwaniach, z polamiName(string) iCompleted(bool) - Utwórz funkcję o nazwie
completeTask, która przyjmuje jako parametry wskaźnik do wycinka strukturTaskoraz indeks (int) - Wewnątrz funkcji
completeTaskzmodyfikuj poleCompletedzadania o podanym indeksie, ustawiając je natrue - Użyj
bufio.Scanner, aby prawidłowo odczytać wiersze danych wejściowych:- Utwórz skaner:
scanner := bufio.NewScanner(os.Stdin) - Dla każdego wiersza danych wejściowych wywołaj
scanner.Scan(), a następniescanner.Text() - Dzięki temu nazwy zadań zawierające spacje zostaną poprawnie odczytane
- Utwórz skaner:
- Przetwórz dane zadań z drugiego wejścia, aby utworzyć wycinek zadań:
- Podziel dane wejściowe po przecinkach, aby uzyskać poszczególne wpisy zadań
- Dla każdego wpisu podziel go po dwukropku, aby oddzielić nazwę od statusu
- Przekonwertuj łańcuch statusu na wartość logiczną (
"true"staje siętrue, a"false"staje sięfalse)
- Przekonwertuj trzeci łańcuch wejściowy na liczbę całkowitą, aby uzyskać indeks zadania
- Wywołaj funkcję
completeTask, przekazując jej wskaźnik do wycinka i indeks - Po ukończeniu zadania wyświetl wszystkie zadania w tym samym formacie co w poprzednim wyzwaniu:
- W przypadku ukończonych zadań:
"[x] [task_name]" - W przypadku nieukończonych zadań:
"[ ] [task_name]"
- W przypadku ukończonych zadań:
- Wyświetl komunikat potwierdzający:
"Task '[task_name]' marked as completed!" - Wyświetl zaktualizowane podsumowanie:
"Total: [total_count] tasks ([completed_count] completed, [incomplete_count] remaining)"
Użyj pakietu strconv, aby przekonwertować łańcuch indeksu na liczbę całkowitą. To wyzwanie pokazuje, jak odbiorcy wskaźnikowi umożliwiają modyfikowanie oryginalnej struktury danych, dzięki czemu zmiany listy zadań są trwałe i pozostają po zakończeniu działania funkcji.
Spróbuj swoich sił
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)
}Wszystkie lekcje w sekcji Logika i przepływ sterowania
1Zaawansowane sterowanie przepływem
Instrukcja switch z `fallthrough`Przerywanie zagnieżdżonych pętliKontynuowanie określonej pętliInstrukcja `goto`Podsumowanie — zaawansowane sterowanie pętlami4Projekt: Prosta lista zadań
Konfiguracja projektuDodawanie zadania2Struktury i metody
Definiowanie metod dla strukturOdbiorniki przez wartośćOdbiorniki przez wskaźnikWybór odbiornikówMetody a funkcjePodsumowanie — działanie struktur5Mapy w szczegółach
Mapy strukturWskaźniki jako wartości mapSprawdzanie, czy mapy są nilPorównywanie mapPodsumowanie — licznik częstości słów3Interfejsy (podstawy)
Czym jest interfejs?Definiowanie interfejsuImplementowanie interfejsuUżywanie typów interfejsowychPusty interfejsAsercje typuPrzełącznik typówPodsumowanie – kształty i zachowaniaPoćwicz samodzielnie: Kompilator Go online