[The Go Programming Language] 2장 프로그램 구조 - 2.5 타입 선언
안녕하세요. 개발자 모도리입니다.
The Go Programming Language 라는 책으로 Go를 공부하고 있으며, 해당 책의 내용을 요약 정리해서 올리려고 합니다. 저는 번역본을 구매해서 공부하고 있습니다.
예제코드 라고 나오는 것들은 https://github.com/modolee/tgpl.git 에서 다운 받으실 수 있습니다.
지난 게시물
- [Go] Mac에서 Atom으로 Go 개발 환경 구축하기
- [The Go Programming Language] 1장 튜토리얼 - 1.1 Hello, World
- [The Go Programming Language] 2장 프로그램 구조 - 2.1 이름
- [The Go Programming Language] 2장 프로그램 구조 - 2.2 선언
- [The Go Programming Language] 2장 프로그램 구조 - 2.3 변수
- [The Go Programming Language] 2장 프로그램 구조 - 2.4 할당
2장 프로그램 구조
2.5 타입 선언
변수의 사용
- 변수나 표현식의 타입은 크기, 내부 표현 방식, 수행 가능한 고유 작업, 연관된 메소드와 같은 해당 값의 특성을 정의합니다.
- 모든 프로그램에는 동일하게 표현하지만, 매우 다른 개념의 가진 변수가 있습니다.
int
: 루프 인덱스, 타임스탬프, 파일 디스크립터, 개월 수float64
: 길이(m), 속도(m/s), 온도string
: 암호, 색상의 이름
새로운 명명된 타입
- 타입 선언은 기존 타입과 같은 내부 타입을 갖는 새 명명된 타입을 정의합니다.
- 명명된 타입은 별개의 호환되지 않을 수도 있는 내부 타입에 이름을 붙여 의도치 않게 섞이지 않도록 합니다.
type 이름 내부타입
- 타입 선언은 명명된 타입을 패키지 전체에서 볼 수 있는 패키지 수준에서 가장 많이 나타나며, 이름이 export되면(대문자로 시작할 때) 다른 패키지에서도 볼 수 있습니다.
섭씨, 화씨 온도 타입 선언
- 이 패키지는 온도의 두 가지 단위에 Celsius(섭씨), Fahrenheit(화씨)의 두 타입을 정의합니다.
- 둘 다 동일한 내부 타입인 float64를 사용하지만 동일한 타입이 아니기 때문에 산술식으로 비교하거나 결합할 수 없습니다. 이 덕분에 무심코 서로 다른 단위의 온도를 조합하는 오류를 방지할 수 있습니다.
package tempconv0
import "fmt"
type Celsius float64
type Fahrenheit float64
const (
AbsoluteZeroC Celsius = -273.15
FreezingC Celsius = 0
BoilingC Celsius = 100
)
func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) }
func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 / 9) }
func (c Celsius) String() string { return fmt.Sprintf("%gºC", c) }
예제코드 [ch2/tempconv0/tempconv0.go]
사용 예제
- Example1 - 산술 연산자
- 명명된 타입의 내부 타입이 구조와 표현 및 지원되는 고유의 작업을 결정하며, 이는 내부 타입을 직접 사용할 때와 마찬가지입니다.
- 즉, 산술 연산자는 예상했듯이 Celsius와 Fahrenheit에서 float64와 동일하게 동작합니다.
- Example2 - 비교 연산자
- 명명된 타입과 동일한 타입이나 동일한 내부 타입을 가진 이름 없는 타입의 값은
==
나<
같은 비교 연산자로 비교할 수 있습니다.
- 명명된 타입과 동일한 타입이나 동일한 내부 타입을 가진 이름 없는 타입의 값은
- Example3 - 메소드 정의
- 예제코드 [ch2/tempconv0/tempconv0.go]의 마지막 줄에 해당하는 내용입니다.
- Celsius 파라미터 c를 함수명 앞에 표기했으며, c의 숫자 값에 ºC를 붙여 반환하는 String 메소드를 Celsius 타입에 연결합니다.
- 많은 타입이 이런 형태의 String 메소드를 정의해 해당 타입 값이 fmt 패키지에 의해 문자열로 출력 될 때의 출력 형태를 제어합니다.
package tempconv0
import "fmt"
func Example1() {
fmt.Printf("%g\n", BoilingC-FreezingC) // "100"
boilingF := CToF(BoilingC)
fmt.Printf("%g\n", boilingF-CToF(FreezingC)) // "180"
//fmt.Printf("%g\n", boilingF-tempconv0.FreezingC) // 컴파일 오류 : 타입 불일치
}
func Example2() {
var c Celsius
var f Fahrenheit
fmt.Println(c == 0) // "true"
fmt.Println(f >= 0) // "true"
//fmt.Println(c == f) // 컴파일 오류 : 타입 불일치
fmt.Println(c == Celsius(f)) // "true"!
}
func Example3() {
c := FToC(212.0)
fmt.Println(c.String()) // "100ºC"
fmt.Printf("%v\n", c) // "100ºC"
fmt.Printf("%s\n", c) // "100ºC"
fmt.Println(c) // "100ºC"
fmt.Printf("%g\n", c) // "100"; String을 호출하지 않음
fmt.Println(float64(c)) // "100"; String을 호출하지 않음
}
예제코드 [ch2/tempconv0/examples.go]
패키지 사용을 위한 위치 지정
위의 예제코드들은 패키지로 만들어져 있어서 실제 실행을 위해서는 main 패키지를 만들어서 실행해야 합니다.
패키지의 위치는 GOPATH로 지정한 경로의 src 폴더가 루트 경로가 됩니다.
저는~/Dev/go/
를 GOPATH로 지정했습니다.
그래서 package 파일들은~/Dev/go/src/
밑에 저장하고 있으며tgpl/ch2/tempconv0
형태로 폴더를 만들고 패키지 폴더를 만들어서 폴더 별로 패키지를 저장합니다.
그냥 테스트 실행을 위한 파일들은 아래 예제코드와 같이ch2/
루트에 위치해 했습니다.
package main
import (
"fmt"
"tgpl/ch2/tempconv0"
)
func main() {
fmt.Println("<<-- Example1 -->>")
tempconv0.Example1()
fmt.Println("<<-- Example2 -->>")
tempconv0.Example2()
fmt.Println("<<-- Example3 -->>")
tempconv0.Example3()
}
예제코드 [ch2/tempconv0_main.go]
실행결과
$ go run ch2/tempconv0_main.go
<<-- Example1 -->>
100
180
<<-- Example2 -->>
true
true
true
<<-- Example3 -->>
100ºC
100ºC
100ºC
100ºC
100
100
@modolee, I gave you a vote!
If you follow me, I will also follow you in return!