A Tour of Go 1
출처 Go Tour
🚫 아래 내용은 주관적인 생각이므로 사실과 다를 수 있습니다.
Packages
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("My favorite number is", rand.Intn(10))
}
모든 Go 프로그램은 패키지들로 만들어진다
Go 컴파일러가 위 코드 맨 윗줄의 package main를 보고 실행 프로그램으로 인식한다
Imports
import "fmt"
import "math"
패키지를 임포트 할 때, 위와 같이 하나하나 임포트해도 되지만
아래와 같이 그룹지어 임포트 하는 방식(factored import문)을 권장한다
import (
"fmt"
"math/rand"
)
Exported names
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(math.pi)
}
// ./prog.go:9:14: cannot refer to unexported name math.pi
// math.pi를 math.Pi로 바꾸면 3.141592653589793
Go에서는 대문자로 시작하는 이름이 Export되는 이름이다
위 코드 중 main() 안의 fmt.Println(math.pi) 구문은
math에서 대문자로 시작하지 않는 pi를 사용하려하고
이는 에러를 발생시킨다
Functions 1
package main
import "fmt"
func add(x int, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
// 55
함수는 0개 또는 그 이상의 파라미터를 가질 수 있다
위의 코드에서 add 함수는 두 개의 파라미터를 받는데,
변수명 뒤에 타입을 기재하는것을 확인할 수 있다
왜 그러는지는 여기에서 확인할 수 있다
Functions 2
package main
import "fmt"
func add(x, y int) int {
return x + y
}
func main() {
fmt.Println(add(42, 13))
}
// 55
같은 타입의 파라미터를 여러개 받는다면,
타입을 전부 생략하고 마지막에만 붙여줘도 된다
Multiple results
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}
// world hello
함수는 다수의 반환값을 가질수 있다
위 코드의 swap 함수는 2개의 string들을 반환한다
Named return values
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(split(17))
}
// 7 10
위 코드의 split 함수처럼 반환값에도 이름을 정하고, 함수 내에서 사용할 수 있다
또한, 위와 같은 반환 인자가 없는 return문을 naked return문이라고 한다
긴 함수에서는 가독성을 떨어뜨릴수 있기 때문에 짧은 함수에서만 사용하길 권장한다
Variables
package main
import "fmt"
var c, python, java bool
func main() {
var i int
fmt.Println(i, c, python, java)
}
// 0 false false false
위처럼 var문으로 변수 목록을 선언하고
이전 예시들처럼 마지막에 타입을 기재해준다
var문은 패키지나 함수 레벨에서 쓰일 수 있다
Variables with initializers
package main
import "fmt"
var i, j int = 1, 2
func main() {
var c, python, java = true, false, "no!"
fmt.Println(i, j, c, python, java)
}
// 1 2 true false no!
변수를 선언할 때, 변수 하나당 하나의 초기값을 할당할 수 있다
초기값을 할당하고 타입을 생략하면, 변수의 타입은 초기값의 타입으로 정해진다
Short variable declarations
package main
import "fmt"
func main() {
var i, j int = 1, 2
k := 3
c, python, java := true, false, "no!"
fmt.Println(i, j, k, c, python, java)
}
// 1 2 3 true false no!
함수 안에 보이는 := 기호로 짧은 변수 선언이 가능하다
짧은 변수 선언은 var 선언처럼 사용될 수 있으며
타입 또한 암시적으로 할당된다
그러나 함수 밖에서는 모든 구문들이 다른 키워드들로 시작하므로
짧은 변수 선언은 사용할 수 없다
Basic types
Go의 기본적인 타입들은 아래와 같다
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // uint8와 같다
rune // int32와 같다
// Unicode 중 code point를 나타낸다
float32 float64
complex64 complex128
아래의 예시에서 몇 가지 타입의 변수들과
import문처럼 블록 안에서 factored 형태로 선언되는 방식을 확인할 수 있다
int, uint, uintptr 타입들은 보통
시스템에 따라 32-bit 시스템에서는 32 bit,
64-bit 시스템에서는 64 bit의 길이를 가진다
정수 값을 쓸 때는 특별한 상황이 아니라면 int를 사용하자
package main
import (
"fmt"
"math/cmplx"
)
var (
ToBe bool = false
MaxInt uint64 = 1<<64 - 1
z complex128 = cmplx.Sqrt(-5 + 12i)
)
func main() {
fmt.Printf("Type: %T Value: %v\n", ToBe, ToBe)
fmt.Printf("Type: %T Value: %v\n", MaxInt, MaxInt)
fmt.Printf("Type: %T Value: %v\n", z, z)
}
// Type: bool Value: false
// Type: uint64 Value: 18446744073709551615
// Type: complex128 Value: (2+3i)
Zero values
package main
import "fmt"
func main() {
var i int
var f float64
var b bool
var s string
fmt.Printf("%v %v %v %q\n", i, f, b, s)
}
// 0 0 false ""
명시적인 초기값 없이 선언된 변수들은 각 타입에 맞는 zero vlaue를 갖는다
- 숫자들은 0
- 불리언은 false
- String은 “”
Type conversions
package main
import (
"fmt"
"math"
)
func main() {
var x, y int = 3, 4
var f float64 = math.Sqrt(float64(x*x + y*y))
var z uint = uint(f)
fmt.Println(x, y, z)
}
// 3 4 5
표현식 T(v) 에서 값 v는 T 타입으로 변환된다
몇가지 숫자 형변환 예시
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
아니면 아래와 같이 더 간단하게 할 수도 있다
i := 42
f := float64(i)
u := uint(f)
C랑은 다르게 Go에서는 명시적인 형변환이 필요하다
Type inference
package main
import "fmt"
func main() {
v := 42 // change me!
fmt.Printf("v is of type %T\n", v)
}
// v is of type int
명시적으로 타입을 지정 안해주면 우측의 값을 보고 추론한다
우측의 값의 타입이 이미 정해져있다면, 그 타입을 그대로 따른다
var i int
j := i // i가 int니까 j도 int다
그러나 우측의 값이 지정되지 않은 타입의 숫자인 경우에는
그 정밀도를 보고 추론한다
i := 42 // int
f := 3.142 // float64
g := 0.867 + 0.5i // complex128
Constants
package main
import "fmt"
const Pi = 3.14
func main() {
const World = "世界"
fmt.Println("Hello", World)
fmt.Println("Happy", Pi, "Day")
const Truth = true
fmt.Println("Go rules?", Truth)
}
// Hello 世界
// Happy 3.14 Day
// Go rules? true
상수는 변수처럼 선언되지만 var 키워드 대신 const 키워드를 사용한다
상수는 character, string, boolean, numeric값이 될 수 있으며
:= 기호(짧은 변수 선언)로는 선언이 불가하다
Numeric Constants
package main
import "fmt"
const (
// 1 비트를 왼쪽으로 100번 시프트해서 큰 숫자를 만들어보자
// 1 뒤에 0이 100개 붙은 이진수가 된다
Big = 1 << 100
// 다시 오른쪽으로 99번 시프트 해보자. 1<<1, 즉, 2가 된다
Small = Big >> 99
)
func needInt(x int) int {
return x * 10 + 1
}
func needFloat(x float64) float64 {
return x * 0.1
}
func main() {
fmt.Println(needInt(Small))
fmt.Println(needFloat(Small))
fmt.Println(needFloat(Big))
}
// 21
// 0.2
// 1.2676506002282295e+29
// fmt.Println(needInt(Big))으로 바꾸면 아래와 같은 에러가 발생한다
// ./prog.go:19:21: constant 1267650600228229401496703205376 overflows int
변수에 값을 할당할 때, 변수가 값을 담기에 충분한지 확인하자
댓글남기기