Control
For 문
Go에는 for 루프라는 단 하나의 루핑 구조만 있습니다.
기본 for 루프에는 세미콜론으로 구분된 세 가지 구성 요소가 있습니다.
- init 문: 첫번째 반복전에 실행
- 조건식: 모든 반복전에 평가
- post 문: 모든 반복의 끝에서 실행
init문은 종종 짧은 변수 선언이며 선언된 변수는 for 문의 범위에서만 작동
init문과 post 문은 생략할 수 있음. 이 경우는 for 문은 다른 언어의 while과 같은 역할을 함
조건문을 생략할 경우 for 문은 종결되지 않음
bool 조건이 false이면 반복은 중지됩니다.
참고: C, Java 또는 JavaScript와 같은 다른 언어와 달리 for 문의 세 가지 구성 요소를 둘러싼 괄호가 없으며 중괄호 { }는 항상 필요합니다.
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
//init문과 post 문 없이 작동
//다른 언어의 while과 같은 역할
total := 1
for total < 100 {
total += total
}
fmt.Println(total)
}
if 문
if 조건 { }
for와 마찬가지로 if 문장은 조건 전에 실행할 짧은 문장으로 시작할 수 있습니다. 또한 if 문 내에 선언된 변수는 if가 끝날 때까지만 범위에 있습니다.
package main
import (
"fmt"
"math"
)
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
9 20
위 코드에서 변수 v는 if 문내에서만 작동합니다. 그러므로 $v=x^n$이 조건에 참일 경우 if문 내부의 return 문이 실행됩니다. return문의 실행으로 함수가 종결됩니다. 이 조건이 거짓일 경우 if 문은 실행되지 않고 외부에 있는 return 문이 실행됩니다.
if ~ else
다음 구조와 같이 else 문은 if문이 종결되는 같은 행에 시작합니다.
if 짧은 문;조건{
} else{
}
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >=%g\n", v, lim)
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
27 >=20
9 20
위 코드에서 main()함수내의 pow()가 실행되면서 전체 프로그램이 시작됩니다. 특히 pow(3, 3, 20)의 경우 else{} 문 내의 printf()가 실행되어 main()의 결과가 출력되기 전에 먼저 실행됩니다.
연습
함수와 루프를 가지고 놀기 위해 제곱근 함수를 구현해 보겠습니다. 숫자 x가 주어졌을 때, z²가 x에 가장 가까운 숫자 z를 찾고 싶습니다.
컴퓨터는 일반적으로 루프를 사용하여 x의 제곱근을 계산합니다. 추측 z로 시작하여 z²가 x에 얼마나 가까운지에 따라 z를 조정하여 더 나은 추측을 생성할 수 있습니다.
$$z -=\frac{z^2-x}{2z}$$
이 조정을 반복하면 추측이 점점 더 좋아져서 실제 제곱근에 가능한 한 가까운 답에 도달할 때까지 계속됩니다(뉴턴 방정식 참조).
package main
import (
"fmt"
"math"
)
func Sqrt(x float64) float64 {
z := 1.0
for i := 1; i < 1000; i++ {
z -= (z*z - x) / (2 * z)
if z-math.Sqrt(x) < 0.000001 {
break
}
}
return z
}
func main() {
x := float64(0)
for i := 0; i < 10; i++ {
x += 1
fmt.Println(Sqrt(x))
}
}
1
1.4142135623746899
1.7320508100147276
2.0000000929222947
2.2360688956433634
2.4494897427875517
2.6457513111113693
2.8284271250498643
3.000000001396984
3.162277665175675
switch 문
switch문은 if-elsw 문 시퀀스를 작성하는 더 짧은 방법입니다. 조건 표현식과 값이 같은 첫번째 케이스를 실행합니다. Go의 switch는 선택된 케이스만을 실행하고 그 뒤에 오는 모든 케이스를 실행하지 않습니다. 이것은 각 케이스 의 끝에 필요한 break 문이 자동으로 제공된다고 생각할 수 있습니다. 또한 다른 언어와 차이점은 각 케이스는 상수일 필요가 없으며 관련 값은 정수일 필요가 없다는 것입니다.
switch문은 위에서 아래로 각 case를 평가합니다.
import (
"fmt"
"time"
)
func main() {
fmt.Println("When's Saturday?")
today := time.Now().Weekday()
fmt.Println("Today:", today)
switch time.Saturday {
case today + 0:
fmt.Println("Today")
case today + 1:
fmt.Println("Tomorrow")
case today + 2:
fmt.Println("In two days")
case today + 3:
fmt.Println("In three days")
default:
fmt.Println("Too far away")
}
}
When's Saturday?
Today: Tuesday
Too far away
다음 코드는 switch문의 기본 형태이며 지정된 변수와 같은 case문의 내용을 출력합니다.
package main
func textPoint(x int) int {
return x
}
func main() {
var text string
number := textPoint(2)
switch number {
case 1:
text = "Number 1"
case 2:
text = "Number 2"
case 3, 4:
text = "Number 3,4"
default:
text = "Other"
}
println(text)
}
Number 2
switch 문에 짧은 문(statement)를 작성할 수 있습니다.
func textPoint(x int) int {
return x
}
func main() {
var text string
number := textPoint(1)
//numbe를 왼쪽으로 2칸 이동 _ _ 1이므로 number=2**2=4입니다.
switch x := number << 2; x - 1 {
case 1:
text = "Number 1"
case 2:
text = "Number 2"
case 3, 4:
text = "Number 3,4"
default:
text = "Other"
}
println(text)
}
Number 3,4
case 문에 표현식(expression)을 작성할 수 있습니다.
func textPoint(x int) int {
return x
}
func main() {
var text string
number := textPoint(2)
switch number {
case number - 1:
text = "Number 1"
case number:
text = "Number 2"
case 3, 4:
text = "Number 3,4"
default:
text = "Other"
}
println(text)
}
Number 2
switch 문은 변수 또는 식, 문을 포함하지 않을 수 있습니다. 대신에 각 case 문이 이들을 포함하여야 합니다. 다음 코드에서 number=2입니다. 두번째와 3번째 case 문에 해당합니다. 그러므로 부합하는 case 문 이후의 모든 명령이 자동 종결되므로 3번째 case 문은 실행되지 않습니다.
func textPoint(x int) int {
return x
}
func main() {
var text string
number := textPoint(2)
switch {
case number == 1:
text = "Number 1"
case number > 1:
text = "Number 2"
case 2 <= number && number < 5:
text = "Number 3,4"
default:
text = "Other"
}
println(text)
}
Number 2
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("좋은 아침입니다.")
case t.Hour() < 17:
fmt.Println("멋진 오후입니다.")
default:
fmt.Println("부드러운 저녁입니다.")
}
}
부드러운 저녁입니다.
defer참조
Go에는 제어 흐름에 대한 일반적인 메커니즘이 있습니다: if, for, switch, goto. 또한 별도의 고루틴에서 코드를 실행하는 go 문도 있습니다. 여기서는 덜 일반적인 것들 중 일부인 defer에 대해 논의합니다.
defer 문은 주변 함수가 반환될 때까지 함수 실행을 연기합니다. 연기된 호출의 인수는 즉시 평가되지만 함수 호출은 주변 함수가 반환될 때까지 실행되지 않습니다.
import "fmt"
func main() {
defer fmt.Println("World")
fmt.Println("Hello")
}
Hello
World
Stacking defer
지연된 함수 호출은 스택에 푸시됩니다. 함수가 반환되면 지연된 호출은 후입선출 순서(last-in-first-out order)로 실행됩니다.
댓글
댓글 쓰기