Go 언어의 `range` 문은 어떻게 사용하나요?
_____A1: `range` 문은 Go에서 배열, 슬라이스(slice), 문자열, 맵(map), 채널 채널(channel)과 같은 컬렉션을 순회(iterate)하기 위한 반복문입니다. 각 요소와 인덱스(또는 키, 값)를 편리하게 얻을 수 있게 해줍니다.
---
Q2: 기본적인 `range` 구문은 어떻게 생겼나요?
A2:
```go
for index, value := range collection {
// index와 value를 사용한 처리
}
```
여기서 `collection`은 배열, 슬라이스, 맵, 문자열 등이며, `index`는 인덱스 또는 키, `value`는 컬렉션 내 해당 위치의 값입니다.
---
Q3: 배열이나 슬라이스를 `range`로 순회할 때 어떻게 하나요?
A3:
```go
nums := []int{10, 20, 30}
for i, v := range nums {
fmt.Println(i, v)
}
```
`i`는 인덱스, `v`는 해당 인덱스의 값입니다.
---
Q4: 인덱스 값만 사용하려면 어떻게 하나요?
A4: 인덱스만 필요하면 값 자리에 `_`를 대입합니다.
```go
for i := range nums {
fmt.Println("Index:", i)
}
```
---
Q5: 값만 사용하려면 어떻게 하나요?
A5: 인덱스가 필요 없으면 변수 이름을 `_`로 하고 값만 받습니다.
```go
for _, v := range nums {
fmt.Println("Value:", v)
}
```
---
Q6: 문자열에 `range`를 적용하면 어떻게 되나요?
A6: 문자열을 순회할 때는 각 루프마다 문자열 내의 유니코드 코드 포인트(rune)를 인덱스와 함께 반환합니다.
```go
s := "안녕"
for i, r := range s {
fmt.Printf("Index: %d, Rune: %c\n", i, r)
}
```
여기서 `i`는 바이트 인덱스, `r`은 룬(유니코드 문자)입니다.
---
Q7: 맵(map)을 `range`로 순회하려면 어떻게 하나요?
A7:
```go
m := map[string]int{"a": 1, "b": 2}
for k, v := range m {
fmt.Println(k, v)
}
`k`는 키, `v`는 값입니다. 순서는 랜덤입니다.
---
Q8: 채널(channel)을 `range`로 순회하려면?
A8: 채널을 `range`하면 채널이 닫힐 때까지 값을 받습니다.
```go
ch := make(chan int)
go func() {
ch <- 1
ch <- 2
close(ch)
}()
for v := range ch {
fmt.Println(v)
}
```
---
Q9: `range`문의 변수 역할을 정확히 설명해 주세요.
A9:
- 배열, 슬라이스, 문자열: 첫 번째 변수는 인덱스(바이트 인덱스 또는 요소 인덱스), 두 번째는 값
- 맵: 첫 번째 변수는 키, 두 번째는 값
- 채널: 값만 받음
---
Q10: `range`문을 사용할 때 주의할 점은?
A10:
- 맵 순회는 무작위 순서입니다.
- 루프 변수는 같은 메모리 공간을 재사용하므로 클로저 안에서 사용 시 주의해야 합니다. 예를 들어:
```go
for i, v := range nums {
go func(n int) {
fmt.Println(n)
}(v) // i 대신 v를 매개변수로 넘기는 것이 안전
}
```
---
Q11: 문자열 `range`에서 인덱스가 바이트 단위인 이유는?
A11: 문자열 내부는 UTF-8 인코딩이므로, `range`에서 `i`는 각 문자의 첫 바이트 인덱스를 반환합니다. 이것은 멀티바이트 유니코드 문자를 처리할 때 유용합니다.
---
Q12: `range` 문을 이용해 슬라이스를 역순으로 순회할 수 있나요?
A12: `range` 자체는 역순 순회를 지원하지 않지만, 인덱스를 이용해 직접 작성할 수 있습니다:
```go
for i := len(slice)-1; i >= 0; i-- {
fmt.Println(slice[i])
}
```
---
요약:
- `range`는 자료구조를 간편히 순회하는 반복문
- 반환값은 구조에 따라 (인덱스, 값) 또는 (키, 값), 채널은 값만
- 인덱스나 값을 생략할 땐 `_` 사용
- 맵 순회는 무작위 순서
- 문자열은 유니코드 문자 단위 순회이며 인덱스는 바이트 위치
- 클로저와 함께 쓸 때는 변수 복사 주의
이상으로 Go의 `range` 문 사용법 FAQ입니다.
`range` 문을 사용하면 데이터 구조의 요소를 쉽게 순회할 수 있으며, 각 요소의 인덱스와 값을 동시에 가져올 수 있습니다.
아래에서는 `range` 문을 사용하는 방법에 대해 자세히 설명하겠습니다.
1. 슬라이스와 배열에서의 사용 슬라이스와 배열에서 `range` 문을 사용하면 각 요소의 인덱스와 값을 가져올 수 있습니다.
```go package main import "fmt" func main() { // 슬라이스 선언 numbers := []int{1, 2, 3, 4, 5} // range 문을 사용하여 슬라이스 반복 for index, value := range numbers { fmt.Printf("Index: %d, Value: %d\n", index, value) } } ``` 위의 예제에서 `range numbers`는 `numbers` 슬라이스의 각 요소에 대해 반복하며, `index`는 현재 요소의 인덱스, `value`는 해당 인덱스의 값을 나타냅니다.
2. 맵에서의 사용 맵에서도 `range` 문을 사용할 수 있으며, 이 경우 키와 값을 가져올 수 있습니다.
```go package main import "fmt" func main() { // 맵 선언 ages := map[string]int{ "Alice": 30, "Bob": 25, "Charlie": 35, } // range 문을 사용하여 맵 반복 for name, age := range ages { fmt.Printf("Name: %s, Age: %d\n", name, age) } } ``` 이 예제에서는 `ages` 맵의 각 키와 값을 반복하여 출력합니다.
3. 문자열에서의 사용 문자열에 대해 `range` 문을 사용할 경우, 각 문자의 인덱스와 해당 문자를 가져올 수 있습니다.
이때, Go는 UTF-8 인코딩을 사용하므로, 다국어 문자열도 올바르게 처리할 수 있습니다.
```go package main import "fmt" func main() { // 문자열 선언 str := "Hello, 世界" // range 문을 사용하여 문자열 반복 for index, runeValue := range str { fmt.Printf("Index: %d, Rune: %c\n", index, runeValue) } } ``` 위의 예제에서 `runeValue`는 현재 인덱스의 문자를 나타내며, `index`는 해당 문자의 바이트 인덱스를 나타냅니다.
4. 채널에서의 사용 채널에서도 `range` 문을 사용할 수 있으며, 채널에서 값을 수신할 때 유용합니다.
```go package main import ( "fmt" "time" ) func main() { // 채널 생성 ch := make(chan int) // 고루틴을 사용하여 채널에 값 전송 go func() { for i := 0; i < 5; i++ { ch <- i time.Sleep(time.Second) } close(ch) // 채널 닫기 }() // range 문을 사용하여 채널에서 값 수신 for value := range ch { fmt.Println("Received:", value) } } ``` 이 예제에서는 고루틴을 사용하여 채널에 값을 전송하고, `range` 문을 통해 채널에서 값을 수신합니다.
채널이 닫힐 때까지 반복합니다.
5. 인덱스 또는 값만 가져오기 `range` 문에서 인덱스 또는 값 중 하나만 필요할 경우, 언더스코어(`_`)를 사용하여 무시할 수 있습니다.
```go package main import "fmt" func main() { // 슬라이스 선언 fruits := []string{"apple", "banana", "cherry"} // 인덱스는 무시하고 값만 가져오기 for _, fruit := range fruits { fmt.Println("Fruit:", fruit) } // 값은 무시하고 인덱스만 가져오기 for index := range fruits { fmt.Println("Index:", index) } } ``` 이렇게 `range` 문을 사용하면 Go 언어에서 다양한 데이터 구조를 쉽게 반복할 수 있으며, 코드의 가독성을 높이고 오류를 줄이는 데 큰 도움이 됩니다.
`range` 문은 Go의 강력한 기능 중 하나로, 다양한 상황에서 유용하게 사용될 수 있습니다.
작성자:
정지훈 [비회원]
| 작성일자: 1년 전
2024-09-19 01:50:29
조회수: 127 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
조회수: 127 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.