A Tour of Go 2

태그: ,

카테고리: ,

출처 Go Tour

🚫 아래 내용은 주관적인 생각이므로 사실과 다를 수 있습니다.



For 1

package main

import "fmt"

func main() {
	sum := 0
	for i := 0; i < 10; i++ {
		sum += i
	}
	fmt.Println(sum)
}
// 45

Go는 반복문이 for문 단 하나다
for문은 세미콜론(;)을 경계로 세 부분으로 나눌 수 있다

  • 초기화 부분 : 순환 이전에 변수 등을 선언하거나 초기화 하는 부분
  • 순환 조건 부분 : 순환하기 위한 조건을 판별하는 부분, 결과가 거짓이면 순환을 멈춘다
  • 순환 후 처리 부분 : 매 순환이 끝날 때 마다 실행되는 부분

Go의 for문은 다른 언어들이랑 다르게 괄호()를 사용하지 않고
순환 내용부를 감싸는 중괄호{}가 필수다


For 2

package main

import "fmt"

func main() {
	sum := 1
	for ; sum < 1000; {
		sum += sum
	}
	fmt.Println(sum)
}
// 1024

for문에서 초기화 부분과 순환 후 처리 부분은 필수가 아니다


For is Go’s “while”

package main

import "fmt"

func main() {
	sum := 1
	for sum < 1000 {
		sum += sum
	}
	fmt.Println(sum)
}
// 1024

Go의 for문에서는 세미콜론(;)을 생략할 수 있어서 다른 언어들의 while문처럼 쓸 수도 있다


Forever

package main

func main() {
	for {
	}
}
// timeout running program

순환 조건 부분을 생략하면 무한 루프를 만들 수 있다


If

package main

import (
	"fmt"
	"math"
)

func sqrt(x float64) string {
	if x < 0 {
		return sqrt(-x) + "i"
	}
	return fmt.Sprint(math.Sqrt(x))
}

func main() {
	fmt.Println(sqrt(2), sqrt(-4))
}
// 1.4142135623730951 2i

Go의 if문은 Go의 for문과 비슷하다
조건 부분이 괄호()로 둘러쌓이지 않고,
내용 부분에 중괄호{}가 필수다


If with a short statement

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

for문처럼 if문에도 조건 부분 전에 초기화 부분을 사용할 수 있다
그러나 초기화 부분에서 선언된 변수들의 스코프는 if문 안으로 제한된다
(if문 밖에서 참조하면 에러발생!)


If and else

package main

import (
	"fmt"
	"math"
)

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)
	}
	// can't use v here, though
	return lim
}

func main() {
	fmt.Println(
		pow(3, 2, 10),
		pow(3, 3, 20),
	)
}
// 27 >= 20
// 9 20

if문의 초기화 부분에서 선언된 변수들은 else 구문 안에서도 사용이 가능하다


Exercise: Loops and Functions

package main

import (
	"fmt"
)

func Sqrt(x float64) float64 {
	var z = x
	for z != z - (z*z - x) / (2*z) {
		z -= (z*z - x) / (2*z)
		fmt.Println(z)
	}
	return z
}

func main() {
	fmt.Println(Sqrt(7))
}
// 4
// 2.875
// 2.654891304347826
// 2.6457670441902894
// 2.6457513111113693
// 2.6457513110645907
// 2.6457513110645907

제곱근 함수를 만들면서 함수와 반복문을 사용해보자
제곱근 함수는 x라는 숫자가 주어졌을 때,
$z^2 = x$를 충족하는 z를 찾아주는 함수다

z -= (z*z - x) / (2*z)

위의 조정값을 반영할 때마다 z의 값은 $\sqrt{x}$에 가까워진다


Switch

package main

import (
	"fmt"
	"runtime"
)

func main() {
	fmt.Print("Go runs on ")
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		// freebsd, openbsd,
		// plan9, windows...
		fmt.Printf("%s.\n", os)
	}
}

switch문은 반복되는 if - else구문의 더 짧은 방법이다
조건 부분과 일치하는 첫번째 case를 실행한다

Go의 switch문은 case마다 break문을 사용하지 않아도 자동으로 적용된다
게다가 case값은 상수나 정수일 필요도 없다


Switch evaluation order

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("When's Saturday?")
	today := time.Now().Weekday()
	switch time.Saturday {
	case today + 0:
		fmt.Println("Today.")
	case today + 1:
		fmt.Println("Tomorrow.")
	case today + 2:
		fmt.Println("In two days.")
	default:
		fmt.Println("Too far away.")
	}
}

switch문은 위에서 아래로의 순서로 case를 확인한다


Switch with no condition

package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("Good morning!")
	case t.Hour() < 17:
		fmt.Println("Good afternoon.")
	default:
		fmt.Println("Good evening.")
	}
}

switch 문에 조건 부분을 생략하면 case값이 참인 경우를 확인한다
(아래와 같은 방식으로 작동한다)

switch true

Defer

package main

import "fmt"

func main() {
	defer fmt.Println("world")

	fmt.Println("hello")
}
// hello
// world

Defer문은 다른 함수들이 모두 종료될 때까지 실행을 연기시키는 구문이다


Stacking defers

package main

import "fmt"

func main() {
	defer fmt.Println("counting")

	for i := 0; i < 5; i++ {
		defer fmt.Println(i)
	}

	fmt.Println("done")
}
// done
// 4
// 3
// 2
// 1
// 0
// counting

defer문은 스택 구조(후입선출, FILO)로 쌓이고 수행된다

댓글남기기