Pointer
package main
import "fmt"
func main() {
i, j := 42, 2701
p := &i // point to i
fmt.Println(*p) // read i through the pointer
*p = 21 // set i through the pointer
fmt.Println(i) // see the new value of i
p = &j // point to j
*p = *p / 37 // divide j through the pointer
fmt.Println(j) // see the new value of j
}
result
42
21
73
- Go는 포인터를 지원하고, 포인터는 값의 메모리 주소를 가지고 있다.
- *T 타입은 T 값을 가리키는 포인터이다. 이것의 zero value는 nil 이다.
- Go는 C언어와 다르게 포인터 산술을 지원하지 않는다.
- & 연산자는 피연산자에 대한 포인터를 생성한다.
i := 42
p = &i
fmt.Println(*p) // 포인터 p를 통해 i 읽기
*p = 21 // 포인터 p를 통해 i 설정
Structs (구조체)
package main
import "fmt"
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X)
}
result
4
- 구조체는 필드의 집합체 이다.
- 구조체의 필드는 .(dot)으로 접근할 수 있다.
Arrays
package main
import "fmt"
func main() {
var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)
primes := [6]int{2, 3, 5, 7, 11, 13}
fmt.Println(primes)
}
result
Hello World
[Hello World]
[2 3 5 7 11 13]
- [n]T 타입은 타입이 T인 n 값들의 배열이다.
var a [10]int
- 위 표현은 변수 a를 10개의 정수들의 배열로 선언한 것이다.
- 배열의 길이는 타입의 일부이기 때문에 배열의 크기를 조정할 수 없다.
Slices
package main
import "fmt"
func main() {
primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[1:4]
fmt.Println(s)
}
result
[3 5 7]
- 배열은 고정된 크기를 가지고 있는 반면에 슬라이스는 배열의 요소들을 동적인 크기로, 유연하게 볼 수 있다.
- []T 타입은 T 타입을 원소로 가지는 슬라이스이다.
- 슬라이스는 콜론으로 구분된 두 개의 인덱스(상한과 하한)를 지정하여 형성된다.
a[low : high]
- 위 예시는 첫 번째 요소를 포함하지만 마지막 요소를 제외하는 범위를 선택한다.
- 따라서 위 코드 실행 시 primes[1], primes[2], primes[3] 값을 출력한다.
배열을 참조하는 슬라이스
package main
import "fmt"
func main() {
names := [4]string{
"John",
"Paul",
"George",
"Ringo",
}
fmt.Println(names)
a := names[0:2]
b := names[1:3]
fmt.Println(a, b)
b[0] = "XXX"
fmt.Println(a, b)
fmt.Println(names)
}
result
[John Paul George Ringo]
[John Paul] [Paul George]
[John XXX] [XXX George]
[John XXX George Ringo]
- 슬라이스는 어떤 데이터도 저장할 수 없다.
- 슬라이스는 단지 기본 배열의 한 영역을 나타낸다.
- 슬라이스의 요소를 변경하면 기본 배열의 해당 요소가 수정된다.
- 동일한 기본 배열을 공유하는 다른 슬라이스는 이러한 변경사항을 확인할 수 있다.
- 위 예제에서 슬라이스 b[0] 수정을 통해 names[1] 의 값인 Paul을 XXX로 변경한 것을 확인할 수 있다.
슬라이스에 요소 추가하기
package main
import "fmt"
func main() {
var s []int
printSlice(s)
// append works on nil slices.
s = append(s, 0)
printSlice(s)
// The slice grows as needed.
s = append(s, 1)
printSlice(s)
// We can add more than one element at a time.
s = append(s, 2, 3, 4)
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\\n", len(s), cap(s), s)
}
result
len=0 cap=0 []
len=1 cap=1 [0]
len=2 cap=2 [0 1]
len=5 cap=6 [0 1 2 3 4]
- 슬라이스에 새로운 요소를 추가하는 것이 일반적이다.
- Go는 내장된 append 함수를 제공한다.
Range
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)
}
}
result
2**1 = 2
2**2 = 4
2**3 = 8
2**4 = 16
2**5 = 32
2**6 = 64
2**7 = 128
- for에서 range는 슬라이스 또는 맵의 요소들을 순회한다.
- 슬라이스에서 range를 사용하면, 각 순회마다 두 개의 값이 반환된다. 첫 번째는 인덱스이고, 두 번째는 해당 인덱스 값의 복사본이다. (1,2), (2,4)…
Range index 생략
package main
import "fmt"
func main() {
pow := make([]int, 10)
for i := range pow {
pow[i] = 1 << uint(i) // == 2**i
}
for _, value := range pow {
fmt.Printf("%d\\n", value)
}
}
result
1
2
4
8
16
32
64
128
256
512
- _ 을 할당하여 인덱스 또는 값을 건너뛸 수 있다.
for i, _ := range pow
for _, value := range pow
- 만약 인덱스만을 원하면, 두 번째 변수를 생략할 수 있다.
for i := range pow
Maps
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, -74.39967,
}
fmt.Println(m["Bell Labs"])
}
result
{40.68433 -74.39967}
- 맵은 키과 값을 매핑한다.
- 맵의 zero value는 nil이다. nil 맵은 키도 없고, 키를 추가할 수도 없다.
- make 함수는 주어진 타입의 초기화되고 사용 준비된 맵을 반환한다.
Mutating Maps
package main
import "fmt"
func main() {
m := make(map[string]int)
m["Answer"] = 42
fmt.Println("The value:", m["Answer"])
m["Answer"] = 48
fmt.Println("The value:", m["Answer"])
delete(m, "Answer")
fmt.Println("The value:", m["Answer"])
v, ok := m["Answer"]
fmt.Println("The value:", v, "Present?", ok)
}
result
The value: 42
The value: 48
The value: 0
The value: 0 Present? false
- m 맵에 요소를 추가하거나 업데이트하기
m[key] = elem
- 요소 검색하기
elem = m[key]
- 요소 제거하기
delete(m, key)
- 두 개의 값을 할당하여 키가 존재하는지 테스트할 수 있다.
elem, ok = m[key]
- 만약 key가 m 안에 있다면, ok는 true 이고, 아니라면 false 이다.
- 만약 key가 맵 안에 없다면, elem은 map의 요소 타입의 zero value 이다.
'프로그래밍' 카테고리의 다른 글
[Gotour] 기초 - 흐름 제어 구문: for, if, else, switch 그리고 defer (0) | 2023.05.23 |
---|---|
[Gotour] 기초 - 패키지와 변수 함수 (0) | 2023.05.19 |