패키지 errors 는 오류를 조작하는 기능을 구현한다.
New 함수는 내용만으로 문자 메시지인 오류를 만든다.
Unwrap , Is , As 기능은 다른 오류를 래핑할 수 있는 오류에 대해 작동한다.
유형에 메소드가 있다면 오류가 다른 오류를 래핑한다.
Unwrap() error
e.Unwrap() 이 nil 이 아닌 오류를 반환한다면 e 가 w 을 래핑한다 라고 말한다.
Unwrap 은 래핑된 에러를 언팩한다. 인수의 타입이 Unwrap 함수를 가질 경우, 메소드를 한번 호출한다. 그렇지 않으면 nil 을 반환한다.
래핑된 오류를 만드는 간단한 방법은 fmt.Errorf 를 호출하고 %w 동사에 오류 인수를 적용하는 것이다.
errors.Unwrap(fmt.Errorf("... %w ...", ..., err, ...))
위는 err 를 리턴한다.
Is 는 첫 인수를 순차적으로 풀어 두 번째 인수와 일치하는 오류를 찾는다.
단순한 평등 검사보다 우선적으로 사용해야 한다.
if errors.Is(err, fs.ErrExist)
위는 == 연산보다 바람직 하다.
if err == fs.ErrExist ❌
왜냐면 err 가 fs.ErrExist 를 래핑하면 전자가 성공하기 때문이다.
func As(err error, target interface{}) bool
As 는 target 과 일치하는 err 의 체인에서 첫 번째 오류를 찾고,
그렇다면 target 을 해당 오류 값으로 설정하고 true 를 반환한다.
그렇지 않으면 false 를 반환한다.
체인은 err 자체와 Unwrap 을 반복적으로 호출하여 얻은 오류 시퀀스로 구성된다.
오류 유형은 다른 유형인 것처럼 처리할 수 있도록 As 메소드를 제공한다.
target 이 오류를 구현하는 유형 또는 모든 인터페이스 유형에 대한 nil 이 아닌 포인터가 아니면 패닉으로 나타난다.
func Is(err, target error) bool
오류 체인의 오류가 대상과 일치하는 지 여부를 반환한다.
체인은 err 자체와 Unwrap 을 반복적으로 호출하여 얻은 오류 시퀀스로 구성된다.
오류는 대상과 일치하거나 Is 함수가 true 를 리턴하는 Is (error) bool 메소드를 구현하는 경우 대상과 일치하는 것으로 간주한다.
func New (text string) error
New 는 주어진 텍스트로 포맷하는 오류를 반환한다.
New 에 대한 각 호출은 텍스트가 동일해도 고유한 오류 값을 반환한다.
패키지 sort 는 슬라이스 및 사용자 정의 컬렉션을 정렬하기 위한 기능을 제공한다.
func Float64s (x [] float64)
Float64s 는 float64 조각을 오름차순으로 정렬.
NaN 값은 다른 값보다 먼저 정렬된다.
func Float64sAreSorted(x [] float64) bool
Float64sAreSorted 는 조각 x 가 다른 값보다 먼저 NaN 값을 사용하여 오름차순으로 정렬되는지 여부를 반환
func Ints(x [] int)
Ints 는 int 조각을 오름차순 정렬
finc IntsAreSorted
IntsAreSorted 는 슬라이스 x 가 오름차수능로 정렬됐는지 여부 반환
func IsSorted(data interface) bool
데이터의 정렬 여부를 반환
func Search(n int, f func(int) bool) int
이진 검색으로 f(i) 가 참인 [0, n] 에서 가장 작은 인덱스 i 를 반환
이진 검색이기 때문에 데이터가 내림차순인지 오름차순인지 알 필요가 있다.
오름차순의 데이터에서 5 를 찾기 위해선 다음과 같이
Search (len (data), func (i int) bool {return data [i]> = 5})
별도로 테스트를 진행해야 한다.
오름차순은 >= , 내림차순은 <= 을 사용하자.
위를 이해하기 위해 간단한 예제를 살펴보자.
func main() {
x := 5
data := []int{1, 2, 3, 4, 5}
i := sort.Search (len (data), func (i int) bool {
return data [i] >= x
})
if i <len (data) && data [i] == x {
fmt.Printf("x는 data [%d]에 존재합니다.", i)
}
}
예제를 살펴보면 데이터가 오름차순이고 data[i] >= x 를 확인할 수 있다.
위 결과는 x 는 data [4]에 존재합니다. 가 출력된다.
반대로 data[i] <= x 도 시도해보자.
func SearchFloat64s(a[] float64 ,x float64) int func SearchInts(a[] int ,x int) int func SearchStrings(a []string, x string) int
위 Search[Float64s|Ints|Strings] 는 오름차순 정렬된 슬라이스 중에서 x 를 검색하여 지정된 인덱스를 반환한다.
x 가 없을 경우의 반환 값은 x 를 삽입할 인덱스(len(a) 일 수 있음) 이다.
func Slice(x interface{}, less func(i, j int) bool)
Slize 는 제공된 less 함수로 슬라이스 x 를 정렬한다.
만약 x 가 슬라이스가 아니라면 패닉이 발생한다.
정렬이 안정적이라고 보장할 수 없으며 동일한 요소가 원래 순서에서 반전될 수도 있다.
안정적인 정렬을 위해 SliceStable 를 사용한다.
less 함수는 인터페이스 유형의 Less 메소드와 동일한 요구 사항을 충족해야 한다.
func SliceIsSorted(x interface{}, less func(i, j int) bool) bool
SliceSorted 는 슬라이스 x 가 제공된 less 함수에 따라 정렬되는지 여부를 반환한다.
x 가 슬라이스가 아니라면 패닉이 발생한다.
func SliceStable(x interface{}, less func(i, j int) bool)
SliceStable 은 제공된 less 함수를 사용하여 슬라이스 x 를 정렬하여 동일한 요소를 원래 순서대로 유지한다.
x 가 슬라이스가 아니라면 패닉이 발생한다.
less 함수는 인터페이스 유형의 Less 메소드와 동일한 요구사항을 충족해야 한다.
func Sort(data Interface)
Sort 는 data 를 정렬한다.
data.Len 을 한 번 호출하여 n 을 결정하고 O(n*log(n)) 은 data.Less 와 data.Swap 을 호출한다.
이 정렬은 안전하다고 보장할 수 없다.
func Stable(data Interface)
Stable 는 동등한 요소의 원래 순서를 유지하며 데이터를 정렬한다.
data.Len 을 한 번 호출하여 n 을 결정하고 O(n*log(n)) 은 data.Less 를 호출하고 O(n*log(n)*log(n)) 은 data.Swap 을 호출한다.
func Strings(x []string)
Strings 는 문자열 슬라이스를 오름차순으로 정렬한다.
func StringsAreSorted(x []string) bool
StringsAreSorted 는 슬라이스 x 가 오름차순 정렬인지 여부를 반환한다.
func Reverse(data interface) interface
Reverse 는 데이터의 역순으로 인터페이스를 반환한다.
다음과 같이 사용할 수 있다.
func main() {
s := []int{5, 2, 6, 3, 1, 4} // 정렬되지 않음
sort.Sort(sort.Reverse(sort.IntSlice(s)))
fmt.Println(s) // [6 5 4 3 2 1] 출력
}
다음과 같은 인터페이스의 형태가 있다.
type Interface interface {
// 해당 컬렉션의 요소들의 갯수
Len() int
// i 인 요소가 j 보다 먼저 정렬되는지 여부를 반환
Less(i, j int) bool
// 인덱스 i 와 j 의 순서를 교체한다.
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
다음 인터페이스는 Interface 의 메소드와 각 타입의 슬라이스를 연결한다.
Float64Slice , IntSlice , StringSlice
위 Interface 의 메소드에 추가적으로
Search , Sort 가 있다. (앞서 배운 것들)