서론
이전 글까지 Golang에서 활용하는 타입에 대해서 공부해보았습니다. 이번 블로그를 끝으로 길고 길었던 타입에 대한 설명에 대한 마지막 투고가 될 것으로 예상합니다.
Properties of types and values
Underlying types (기본 타입들)
각 타입 T 에는 기본 타입들이 있습니다. T가 미리 선언된 Bool, 숫자 또는 문자열 타입 중 하나이거나 리터럴 타입이면 해당 기본 타입은 T 그 자체입니다. 그렇지 않으면 T의 기본 타입은 T가 선언에서 참조하는 타입의 기본 타입입니다. 타입 제약 조건의 기본 타입인 타입 매개 변수의 경우 항상 인터페이스입니다.
type (
A1 = string
A2 = A1
)
type (
B1 string
B2 B1
B3 []B1
B4 B3
)
func f[P any](x P) { … }
문자열 A1, A2, B1 및 B2의 기본 유형은 문자열입니다. []B1, B3 및 B4의 기본 유형은 []B1입니다. P의 기본 유형은 interface{} 입니다.
Core types (코어 타입들)
각각의 비 인터페이스 타입 T는 기본 타입 T와 동일한 코어 타입을 갖습니다.
인터페이스 T는 다음 조건 중 하나를 만족하면 코어 타입을 갖습니다.
- T의 타입 집합에 있는 모든 타입의 코어 타입인 단일 타입 U가 있습니다.
- T의 타입 집합에는 E형 요소가 동일한 채널 타입만 포함되며 모든 방향 채널은 동일한 방향을 갖습니다.
- 코어 타입이 있는 다른 인터페이스는 없습니다.
인터페이스의 코어 타입은 충족되는 조건에 따라 다음 중 하나로 결정됩니다.
- U형
- T형이 오직 양방향 채널들을 포함한 경우에는 chan E 타입이고, 존재하는 방향성 채널의 방향에 따라서 chan<- E 혹은 <-chan E 타입
정의에 따르면 코어 타입은 정의된 타입, 타입 매개 변수 혹은 인터페이스 타입이 아닙니다.
코어 타입이 있는 인터페이스의 예제:
type Celsius float32
type Kelvin float32
interface{ int } // int
interface{ Celsius|Kelvin } // float32
interface{ ~chan int } // chan int
interface{ ~chan int|~chan<- int } // chan<- int
interface{ ~[]*data; String() string } // []*data
코어 타입이 없는 인터페이스의 예제:
interface{} // no single underlying type
interface{ Celsius|float64 } // no single underlying type
interface{ chan int | chan<- string } // channels have different element types
interface{ <-chan int | chan<- int } // directional channels have different directions
일부 연산(슬라이스 표현식, 부록 및 복사)은 byte 슬라이스와 문자열을 허용하는 조금 더 느슨한 형태의 코어 타입에 의존합니다. 특히 인터페이스 T의 타입 집합에 모든 타입의 기본 타입인 []btye와 string의 두 가지 타입이 있으면 T의 코어 타입을 btye string 이라고 합니다.
interface{ int } // int (same as ordinary core type)
interface{ []byte | string } // bytestring
interface{ ~[]byte | myString } // bytestring
btye string은 실제 타입이 아니며 변수를 선언하거나 다른 타입을 구성하는데 사용할 수 없습니다. byte 슬라이스 또는 문자열일 수 있는 byte sequence에서 읽는 일부 연산의 동작을 설명하기 위해서만 존재합니다.
Type identity (타입 일치성)
두 가지 유형은 서로 동일하거나 다를 수 있습니다.
명시적으로 명명된 타입은 다른 타입들과는 항상 다릅니다. 그렇지 않다면 두 타입은 기본 타입 리터럴이 구조적으로 동일하다면 동일합니다. 즉, 동일한 리터럴 구조를 가지며 해당 구성 요소가 동일한 타입을 갖는다는 뜻입니다. 자세한 내용은 다음과 같습니다.
- 두 개의 배열 타입은 요소의 타입이 동일하고 배열의 길이가 동일하면 동일합니다.
- 두 슬라이스 타입은 요소의 타입이 동일하면 동일합니다.
- 두 struct 타입은 동일한 필드 순서를 가지며, 해당 필드에 동일한 이름, 동일한 타입 및 동일한 태그가 있으면 동일합니다. 다른 패키지에서 내보내지 않는 필드 이름은 항상 다릅니다.
- 두 포인터 타입은 기본 타입이 동일하면 동일합니다.
- 두 함수 타입은 파라미터와 결과 타입들의 개수가 동일하고, 대응하는 파라미터와 결과 타입들이 같고, 두 함수가 모두 변량적이거나 둘다 같지 않으면 일치하지 않습니다.
- 두 인터페이스 타입은 동일한 타입 집합을 정의하면 동일합니다.
- 두 map 타입은 키 및 요소 타입이 동일하면 동일합니다.
- 두 채널 타입이 동일한 요소 타입과 동일한 방향을 가지면 동일합니다.
- 인스턴스화된 두 타입은 정의된 타입과 모든 타입 인수가 동일하면 동일합니다.
예제를 살펴보면
type (
A0 = []string
A1 = A0
A2 = struct{ a, b int }
A3 = int
A4 = func(A3, float64) *A0
A5 = func(x int, _ float64) *[]string
B0 A0
B1 []string
B2 struct{ a, b int }
B3 struct{ a, c int }
B4 func(int, float64) *B0
B5 func(x int, y float64) *A1
C0 = B0
D0[P1, P2 any] struct{ x P1; y P2 }
E0 = D0[int, string]
)
위 예제 중에서 다음 타입들은 동일합니다
A0, A1, and []string
A2 and struct{ a, b int }
A3 and int
A4, func(int, float64) *[]string, and A5
B0 and C0
D0[int, string] and E0
[]int and []int
struct{ a, b *B5 } and struct{ a, b *B5 }
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
B0과 B1 은 서로 다른 타입 정의에 의해 생성된 새 타입이므로 다릅니다. func(int, float64) *B0 및 func(x int, y float64) *[]string은 B0과 []string이 다르기 때문에 다르고, P1 및 P2는 서로 다른 타입 매개 변수이기 때문에 다릅니다. D0[int, string] 및 struct{x int; y string}은 전자는 인스턴스화된 정의 타입이고 후자는 타입 리터럴이기 때문에 서로 다릅니다.
Method Sets (메서드 집합)
타입의 메서드 집합은 해당 타입의 피연산자에서 호출할 수 있는 메서드를 결정합니다. 모든 타입에는 해당 메서드와 연결된 (가능하면 빈) 메서드 집합이 있습니다:
- 정의된 타입 T의 메서드 집합은 수신기 타입 T와 함께 선언된 모든 메서드로 구성됩니다.
- 정의된 타입 T(T는 포인터도 인터페이스도 아님)에 대한 포인터의 메서드 집합은 수신기 *T 또는 T와 함꼐 선언된 모든 메서드 집합입니다.
- 인터페이스 타입의 메서드 집합은 인터페이스 타입 집합에서 각 타입의 메서드 집합의 교집합입니다. (결과 메서드 집합은 일반적으로 인터페이스에서 선언된 메서드 집합일 뿐입니다.)
- 추가 규칙은 구조체 타입에 대한 섹션에서 설명한 대로 임베디드 필드를 포함하는 구조체(및 구조체에 대한 포인터)에 적용됩니다. 다른 모든 타입에는 빈 메서드 집합이 있습니다.
메서드 집합에서 각 메서드에는 고유한 공백이 없는 메서드 이름이 있어야 합니다.
결론
드디어 타입에 대한 설명이 얼추 끝났고 다음 글부터는 Block 부터 시작해서 선언과 Scope 에 대한 글을 작성할 예정입니다.
'Golang' 카테고리의 다른 글
Golang 입문기 - 문법 3 (2) | 2023.11.20 |
---|---|
Golang 입문기 - 문법 2 (2) | 2023.10.27 |
Golang 입문기 - 문법 1 (2) | 2023.10.24 |
Golang 입문기 - 0 (0) | 2023.10.20 |