Golang Syntax _3
8. 기본 자료형
Go에 존재하는 자료형
- bool : true 혹은 false를 나타내는 부울 타입이다.
- string : 문자열
- int [ int8, int16, int32, int64 ]
- uint [ uint8, uint16, uint32, uint64 ]
- rune [ int32의 alias이다. ] : 대개 유니코드 코드 포인트 값을 표현하는데 사용된다.
- float32, float64
- complex64, complex128
+ Go에선 Type casting을 위해선 uint8(10)과 같이 castring 할 수 있다.
9. 구조체 (struct)
type Vertex struct { X int Y int } func main() { v := Vertex{1, 2} v.X = 4 fmt.Println(v.X) }
type 구조체이름 struct { ... }
으로 정의하고,구조체이름( ... )
으로 선언한다.- 구조체 필드에 속한 데이터는 dot(.)으로 접근할 수 있다.
- 구조체 리터럴(Struct Literals)은 필드와 값을 나열해 구조체를 새로 할당하는 방법이다.
순서의 상관없이{name: value}
구문을 통해 할당 할 수 있다.package main import "fmt" type Vertex struct { X, Y int } var ( p = Vertex{1, 2} // has type Vertex r = Vertex{X: 1} // Y:0 is implicit s = Vertex{} // X:0 and Y:0 ) func main() { fmt.Println(p, r, s) // {1 2} {1 0} {0 0} }
10. 포인터
Go에선 포인터는 & 접두어로 사용되며, C처럼 포인터 연산은 지원하지 않는다.
package main import "fmt" type Vertex struct { X int Y int } func main() { p := Vertex{1, 2} q := &p q.X = 1e9 fmt.Println(p) // {1000000000 2} }
- C에서의 동작과 유사하게 돌아간다. ( 포인터를 통해 접근시 가르키고 있는 데이터도 변경이 이루어짐 )
- 포인터 연산이 안되니 오히려 C++의 참조자와 비슷한것아닌지…(주관적인생각)
11. new 함수
new(T)는 모든 필드가 0(Zero value)이 할당된 T 타입의 포인터를 반환한다.
(Zero value는 숫자 타입에서는 0, 참조 타입에선 nil을 뜻한다.)
package main import "fmt" type Vertex struct { X, Y int } func main() { v := new(Vertex) // or var v *Vertex = new(Vertex) fmt.Println(v) v.X, v.Y = 11, 9 fmt.Println(v) // &{0 0} &{11 9} }
12. 슬라이스 (Slices)
슬라이스란 Go에서의 배열의 값을 가르킨다. 그리고 배열의 길이(length)를 가지고 있다.
package main import "fmt" func main() { p := []int{2, 3, 5, 7, 11, 13} fmt.Println("p ==", p) fmt.Println("p[1:4] ==", p[1:4]) // missing low index implies 0 fmt.Println("p[:3] ==", p[:3]) // missing high index implies len(s) fmt.Println("p[4:] ==", p[:]) /** Output ** p == [2 3 5 7 11 13] p[1:4] == [3 5 7] p[:3] == [2 3 5] p[4:] == [2 3 5 7 11 13] */ }
- 슬라이스는
[]T
이렇게 선언 할 수 있으며 T 타입의 요소를 가지는 슬라이스이다. - 슬라이스에 저장된 데이터를 가져올때
[0보다 큰값:슬라이스의 길이보다 작은 값]
을 통해서 부분적으로 잘라서 가져올 수 있다. [lo:hi]
일 경우 슬라이스의lo
번째 데이터에서hi-1
번째 데이터 까지 가져온다. 전체를 가져오고 싶은 경우,
[:]
을 통해서 모든 값을 가져 올 수 있다.- 슬라이스는
make(타입, 길이, 용량)
함수를 통해서 만들 수 있다.
cap()
함수는 슬라이스의 용량(capacity)를 가져온다.package main import "fmt" func main() { a := make([]int, 5) printSlice("a", a) b := make([]int, 0, 5) printSlice("b", b) c := b[:2] printSlice("c", c) d := c[2:5] printSlice("d", d) fmt.Println(b[:4]) } func printSlice(s string, x []int) { fmt.Printf("%s len=%d cap=%d %v\n", s, len(x), cap(x), x) } /** Output ** a len=5 cap=5 [0 0 0 0 0] b len=0 cap=5 [] c len=2 cap=5 [0 0] d len=3 cap=3 [0 0 0] [0 0 0 0] */
- 빈 슬라이스는 슬라이스의 zero value가 nil 이다.
- nil 슬라이스는 길이와 용량이 이다.
package main import "fmt" func main() { var z []int fmt.Println(z, len(z), cap(z)) if z == nil { b := [...]string{"Penn", "Teller"} fmt.Println("nil!", cap(b)) } } /** Output ** [] 0 0 nil! 2 */
13. 레인지 Range
for 반복문에서 range를 사용하면 슬라이스나 맵을 순회(iterates)할 수있다.
package main import "fmt" var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} func main() { for i, v := range pow { fmt.Printf("2**%d = %d\n", i, v) } } /** Output ** 2**0 = 1 2**1 = 2 2**2 = 4 2**3 = 8 2**4 = 16 2**5 = 32 2**6 = 64 2**7 = 128 */
for index, value := range pow {...}
에서 index와 value는 슬라이스의 index와 value를 의미한다.- 만약 index나 value를 무시하려면
_
를 통해서 무시하고 진행 할 수 있다.
for _, v := range pow {...}
orfor i := range pow {...}
14. 슬라이스 연습
Pic
이라는 함수를 구현합니다. 이 함수는dy
개 만큼의 길이를 가지는 슬라이스를 리턴해야 하는데, 각각의 요소들은 또한dx
개의 8비트 부호없는 8비트 정수 타입을 가지는 슬라이스입니다. 프로그램을 실행하면 이 정수값들을 흑백 (사실은 파란색)을 나타내는 값으로 해석하여 그림을 보여줄 것입니다.
package main import "code.google.com/p/go-tour/pic" func Pic(dx, dy int) [][]uint8 { y := make([][]uint8, dy, dy) for i := 0; i < int(dy); i++{ y[i] = make([]uint8, dx, dx) } for i, pe := range y { for x := 0; x < dx; x++{ pe[x] = uint8(x) ^ uint8(i) } } return y } func main() { pic.Show(Pic) }
=== Output ===