Concluindo uma Tarefa
Parte da seção Lógica & Fluxo do Journey de GO da Coddy. Lição 23 de 68.
Desafio
FácilNesta parte do seu sistema de gerenciamento de tarefas, você implementará a capacidade de marcar tarefas como concluídas. Este desafio se concentra no uso de receivers de ponteiro para modificar os dados originais da tarefa, demonstrando como os ponteiros permitem atualizar campos de structs permanentemente.
Observação importante: Como os nomes das tarefas podem conter espaços (como "Buy groceries"), você precisará usar bufio.Scanner para ler linhas inteiras da entrada. A função fmt.Scanf para de ler no primeiro espaço, o que causaria problemas nos nomes de tarefas com espaços. Use bufio.NewScanner(os.Stdin) e chame scanner.Scan() seguido de scanner.Text() para ler linhas completas.
Você receberá três entradas:
- Uma string representando o número de tarefas (por exemplo,
"4") - Uma string contendo os dados das tarefas no formato:
"name1:status1,name2:status2,name3:status3", em que status é"true"ou"false"(por exemplo,"Buy groceries:false,Call dentist:true,Finish project:false,Review code:false") - Uma string representando o índice da tarefa a ser concluída (por exemplo,
"2"para a terceira tarefa, usando indexação baseada em 0)
Sua tarefa é:
- Definir a mesma struct
Taskdos desafios anteriores, com os camposName(string) eCompleted(bool) - Criar uma função chamada
completeTaskque receba como parâmetros um ponteiro para uma slice de structsTaske um índice (int) - Dentar da função
completeTask, modificar o campoCompletedda tarefa no índice fornecido paratrue - Usar
bufio.Scannerpara ler corretamente as linhas de entrada:- Criar um scanner:
scanner := bufio.NewScanner(os.Stdin) - Para cada linha de entrada: chamar
scanner.Scan()e depoisscanner.Text() - Isso garante que os nomes de tarefas com espaços sejam lidos corretamente
- Criar um scanner:
- Analisar os dados das tarefas da segunda entrada para criar sua slice de tarefas:
- Dividir a entrada por vírgulas para obter as entradas individuais das tarefas
- Para cada entrada, dividir por dois-pontos para separar o nome e o status
- Converter a string de status em um booleano (
"true"torna-setrue,"false"torna-sefalse)
- Converter a string da terceira entrada em um inteiro para obter o índice da tarefa
- Chamar sua função
completeTaskcom um ponteiro para sua slice e o índice - Depois de concluir a tarefa, exibir todas as tarefas usando o mesmo formato do desafio anterior:
- Para tarefas concluídas:
"[x] [task_name]" - Para tarefas incompletas:
"[ ] [task_name]"
- Para tarefas concluídas:
- Imprimir uma mensagem de confirmação:
"Task '[task_name]' marked as completed!" - Imprimir o resumo atualizado:
"Total: [total_count] tasks ([completed_count] completed, [incomplete_count] remaining)"
Use o pacote strconv para converter a string do índice em um inteiro. Este desafio demonstra como os receivers de ponteiro permitem modificar a estrutura de dados original, fazendo alterações permanentes na sua lista de tarefas que persistem depois que a função retorna.
Experimente você mesmo
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)
}Todas as lições de Lógica & Fluxo
1Fluxo de Controle Avançado
Switch com `fallthrough`Interrompendo Loops AninhadosContinuando um Loop EspecíficoA Instrução `goto`Recapitulação - Controle de Loop Avançado4Projeto: Lista de Tarefas Simples
Configuração do ProjetoAdicionando uma Tarefa2Structs e Métodos
Definindo Métodos em StructsRecebedores de ValorRecebedores de PonteiroEscolhendo RecebedoresMétodos vs FunçõesRecapitulação - Comportamento de Structs5Mapas em Profundidade
Mapas de StructsPonteiros como Valores de MapVerificando Mapas NilComparando MapasRecapitulação - Contador de Frequência de Palavras3Interfaces (O Básico)
O que é uma Interface?Definindo uma InterfaceImplementando uma InterfaceUsando Tipos de InterfaceInterface VaziaAsserções de TipoType SwitchRecapitulação - Formas e ComportamentosPratique por conta própria: Compilador de Go online