sort.Interface
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 74번째.
sort 패키지는 인터페이스 기반 설계의 또 다른 훌륭한 예를 제공합니다. 사용자 지정 컬렉션을 정렬하려면 해당 타입이 sort.Interface를 구현해야 합니다.
type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}이 세 가지 메서드는 정렬 알고리즘에 필요한 모든 것을 제공합니다. collection의 length, elements를 비교하는 방법, 그리고 elements를 교환하는 방법입니다. 사용자 정의 구조체의 슬라이스를 정렬할 수 있도록 만드는 방법은 다음과 같습니다.
type Person struct {
Name string
Age int
}
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func main() {
people := []Person{
{"Alice", 30},
{"Bob", 25},
{"Carol", 35},
}
sort.Sort(ByAge(people))
fmt.Println(people)
// [{Bob 25} {Alice 30} {Carol 35}]
}핵심은 슬라이스를 기반으로 명명된 타입(ByAge)을 만드는 것입니다. 이렇게 하면 동일한 데이터에 대해 서로 다른 정렬 동작을 정의할 수 있습니다. 대신 알파벳순으로 정렬하도록 다른 Less 구현을 사용해 ByName을 만들 수도 있습니다.
사용자 정의 타입이 sort.Interface를 충족하면 sort.Sort(), sort.Reverse(), sort.IsSorted()와 자동으로 함께 작동합니다.
챌린지
쉬움Go의 sort.Interface의 강력한 기능을 보여 주는 정렬 가능한 product inventory 시스템을 만들어 보겠습니다! Product type을 만들고 여러 정렬 전략을 구현하여, 동일한 collection을 다양한 방식으로 정렬할 수 있도록 합니다.
코드는 두 개의 파일로 구성합니다:
product.go: product type과 정렬 구현을 정의합니다.세 개의 field를 가진
Productstruct를 만듭니다:Name(string),Price(float64),Quantity(int).[]Product를 기반으로 하는 두 개의 named type을 만듭니다:ByPrice- price를 ascending order로 정렬ByQuantity- quantity를 descending order로 정렬 (가장 높은 quantity부터)
각 type은
sort.Interface에 필요한 세 가지 method인Len(),Less(i, j int),Swap(i, j int)을 구현해야 합니다.Lessmethod가 각 type의 sort order를 결정합니다.main.go: product inventory를 만들고 정렬합니다.sort mode(
price또는quantity)를 읽은 다음, count와 product details를 읽습니다. 각 product는 name, price, quantity의 세 줄로 제공됩니다.product의 slice를 만들고 mode에 따라 적절한 sorting type을 사용해 정렬한 다음, 각 product를 다음 format으로 출력합니다:
[Name]: $[Price] (x[Quantity])price는 소수점 이하 두 자리로 표시합니다.
다음 입력이 제공됩니다:
- Line 1: Sort mode (
price또는quantity) - Line 2: product의 개수
- Following lines: Product details (name, price, quantity - product당 세 줄)
예를 들어 다음이 주어졌다고 합시다:
price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25출력은 다음과 같아야 합니다:
Mouse: $29.99 (x50)
Keyboard: $79.99 (x25)
Laptop: $999.99 (x5)그리고 다음이 주어졌다고 합시다:
quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25출력은 다음과 같아야 합니다:
Mouse: $29.99 (x50)
Keyboard: $79.99 (x25)
Laptop: $999.99 (x5)다른 named type을 사용하기만 해도 동일한 product data를 다르게 정렬할 수 있다는 점에 주목하세요. type이 sort.Interface를 만족하면 표준 library의 sort.Sort()와 원활하게 함께 사용할 수 있습니다.
직접 해보기
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// 정렬 모드 읽기
var mode string
fmt.Fscanln(reader, &mode)
// 제품 수 읽기
var count int
fmt.Fscanln(reader, &count)
// 제품 읽기
products := make([]Product, count)
for i := 0; i < count; i++ {
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
priceStr, _ := reader.ReadString('\n')
priceStr = strings.TrimSpace(priceStr)
price, _ := strconv.ParseFloat(priceStr, 64)
qtyStr, _ := reader.ReadString('\n')
qtyStr = strings.TrimSpace(qtyStr)
quantity, _ := strconv.Atoi(qtyStr)
products[i] = Product{Name: name, Price: price, Quantity: quantity}
}
// TODO: 모드에 따라 제품 정렬
// mode가 "price"이면 ByPrice 타입 사용
// mode가 "quantity"이면 ByQuantity 타입 사용
// 적절한 타입으로 sort.Sort() 사용
// TODO: 각 제품을 다음 형식으로 출력:
// [Name]: $[Price] (x[Quantity])
// 가격 포맷팅에 %.2f를 사용하여 fmt.Printf 사용
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서11표준 라이브러리 & OOP
io.Reader & io.Writersort.Interfacefmt.Stringer 인터페이스encoding/json과 구조체http.Handler 인터페이스요약 - REST API 모델직접 연습해 보세요: 온라인 Go 컴파일러