요약 - 제네릭 컬렉션
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 72번째.
챌린지
쉬움Go에서 제네릭에 대해 배운 모든 것을 보여주는 제네릭 Queue 데이터 구조를 만들어 봅시다! 스택(LIFO)과 달리 큐는 선입선출(FIFO) 순서를 따릅니다. 즉, 가장 먼저 추가된 항목이 가장 먼저 제거됩니다.
코드는 두 개의 파일로 구성됩니다:
queue.go: 제네릭 큐 컬렉션을 정의합니다.내부적으로 항목을 저장하는 제네릭 구조체
Queue[T any]를 만듭니다. 큐는 다음 연산들을 지원해야 합니다:Enqueue(item T)- 큐의 맨 뒤에 항목을 추가합니다.Dequeue() (T, bool)- 큐의 맨 앞 항목을 제거하고 반환하며, 성공 여부를 나타내는 불리언 값을 함께 반환합니다 (큐가 비어 있으면 제로 값과false를 반환합니다).Peek() (T, bool)- 항목을 제거하지 않고 맨 앞의 항목을 반환합니다 (Dequeue와 동일한 반환 패턴).Size() int- 큐에 있는 항목의 개수를 반환합니다.IsEmpty() bool- 큐에 항목이 없으면 true를 반환합니다.
또한 초기화된 빈 큐의 포인터를 반환하는 생성자 함수
NewQueue[T any]() *Queue[T]를 만듭니다.main.go: 입력에 따라 서로 다른 타입으로 큐를 사용하는 모습을 보여줍니다.타입 표시자(
int또는string)를 읽은 다음, 큐에서 수행할 일련의 명령어를 읽습니다. 각 명령어는 별도의 줄에 있습니다:enqueue [value]- 값을 큐에 추가합니다.dequeue- 맨 앞의 항목을 제거하고 출력합니다 (큐가 비어 있으면empty를 출력합니다).peek- 제거하지 않고 맨 앞의 항목을 출력합니다 (큐가 비어 있으면empty를 출력합니다).size- 현재 크기를 출력합니다.
done을 받을 때까지 명령어를 계속 읽습니다.
다음과 같은 입력이 제공됩니다:
- 1행: 타입 표시자 (
int또는string) - 다음 행들:
done이 나올 때까지의 명령어들
예를 들어, 다음과 같이 입력되면:
int
enqueue 10
enqueue 20
enqueue 30
peek
dequeue
size
dequeue
dequeue
dequeue
done출력은 다음과 같아야 합니다:
10
10
2
20
30
empty그리고 다음과 같이 입력되면:
string
enqueue hello
enqueue world
size
peek
dequeue
peek
done출력은 다음과 같아야 합니다:
2
hello
hello
world여러분의 큐는 정수와 문자열 타입 모두에 대해 동일하게 작동해야 하며, 단일 제네릭 구현이 완전한 타입 안전성을 유지하면서 어떻게 여러 구체적인 타입을 처리하는지 보여주어야 합니다.
직접 해보기
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 타입 표시자를 읽습니다
scanner.Scan()
typeIndicator := scanner.Text()
if typeIndicator == "int" {
// TODO: NewQueue[int]()를 사용하여 정수형 큐를 생성하세요
// 정수형 큐에 대한 명령을 처리합니다
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: 다음 명령들을 처리하세요: enqueue, dequeue, peek, size
// enqueue의 경우, parts[1]에서 정수 값을 파싱하세요
// dequeue/peek의 경우, 큐가 비어 있으면 "empty"를 출력하세요
_ = command
}
} else if typeIndicator == "string" {
// TODO: NewQueue[string]()을 사용하여 문자열 큐를 생성하세요
// 문자열 큐에 대한 명령을 처리합니다
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: 다음 명령들을 처리하세요: enqueue, dequeue, peek, size
// enqueue의 경우, parts[1]의 문자열 값을 사용하세요
// dequeue/peek의 경우, 큐가 비어 있으면 "empty"를 출력하세요
_ = command
}
}
// 이 코드들은 개발 중 사용되지 않는 import 에러를 방지하기 위해 작성되었습니다
_ = strconv.Atoi
_ = fmt.Println
}
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서