할 일 완료하기
Coddy GO 여정의 로직 & 흐름 섹션에 포함된 레슨 — 68개 중 23번째.
챌린지
쉬움작업 관리 시스템의 이번 파트에서는 작업을 완료로 표시하는 기능을 구현하게 됩니다. 이 챌린지는 포인터 리시버를 사용하여 원본 작업 데이터를 수정하는 데 중점을 두며, 포인터가 구조체 필드를 영구적으로 업데이트하는 방법을 보여줍니다.
중요 참고 사항: 작업 이름에 공백이 포함될 수 있으므로(예: "Buy groceries"), 전체 입력 줄을 읽기 위해 bufio.Scanner를 사용해야 합니다. fmt.Scanf 함수는 첫 번째 공백에서 읽기를 중단하므로 공백이 포함된 작업 이름이 잘릴 수 있습니다. bufio.NewScanner(os.Stdin)를 사용하고 scanner.Scan()을 호출한 뒤 scanner.Text()를 호출하여 전체 줄을 읽으세요.
세 가지 입력을 받게 됩니다:
- 작업 수를 나타내는 문자열 (예:
"4") - 다음 형식의 작업 데이터를 포함하는 문자열:
"name1:status1,name2:status2,name3:status3"(여기서 status는"true"또는"false"입니다. 예:"Buy groceries:false,Call dentist:true,Finish project:false,Review code:false") - 완료할 작업의 인덱스를 나타내는 문자열 (예: 세 번째 작업을 위해 0 기반 인덱스를 사용하는
"2")
여러분의 과제는 다음과 같습니다:
- 이전 챌린지와 동일하게
Name(string) 및Completed(bool) 필드를 가진Task구조체를 정의합니다. Task구조체 슬라이스에 대한 포인터와 인덱스(int)를 매개변수로 받는completeTask라는 함수를 만듭니다.completeTask함수 내부에서 지정된 인덱스에 있는 작업의Completed필드를true로 수정합니다.bufio.Scanner를 사용하여 입력 줄을 올바르게 읽습니다:- 스캐너 생성:
scanner := bufio.NewScanner(os.Stdin) - 각 입력 줄에 대해:
scanner.Scan()을 호출한 후scanner.Text()를 호출합니다. - 이렇게 하면 공백이 포함된 작업 이름을 올바르게 읽을 수 있습니다.
- 스캐너 생성:
- 두 번째 입력에서 작업 데이터를 파싱하여 작업 슬라이스를 생성합니다:
- 입력을 쉼표로 분할하여 개별 작업 항목을 얻습니다.
- 각 항목을 콜론으로 분할하여 이름과 상태를 분리합니다.
- 상태 문자열을 불리언으로 변환합니다 (
"true"는true로,"false"는false로).
- 세 번째 입력 문자열을 정수로 변환하여 작업 인덱스를 얻습니다.
- 슬라이스에 대한 포인터와 인덱스를 사용하여
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)
}