프로그래밍 언어/Go

    Go: 변수 스코프와 블록

    렉시컬 블록 렉시컬 블록은 명시적으로 선언되는 블록 뿐만 아니라, if, for, switch, select, case 에서 사용하는 블록과 중괄호로 묶이지 않는 선언의 그룹 및 광역, 패키지, 파일 블록을 모두 포함하는 개념이다. 렉시컬 블록은 블록의 범위를 결정하는데, 이는 스코프라고 부를 수 있다. Go 의 변수는 기본적으로 블록 스코프를 가지기 때문에 블록 외부에서 내부에 선언된 변수에 대해서는 접근하는 것이 불가능하다. 물론 변수의 스코프는 어디에 선언이 되어있는가에 따라 다르다. 함수나 패키지에 선언되어 있을 수도 있어서 함수 스코프가 되기도 하고 패키지 스코프가 되기도 한다. Go 에서의 가장 작은 스코프의 범위가 블록이라는 점은 중요 포인트다. func main() { x := "Hello..

    Go: recover() 를 사용하여 복구하기 [Effective Go]

    recover() 함수를 사용하여 panic() 에서 어플리케이션을 복구할 때 사용할 수는 몇 가지 기법을 Effective Go 에서 보여주고 있다. 이 포스트에서 이야기해 볼 것은 두 가지, 다수의 고루틴을 돌릴 때 다른 고루틴에게 피해를 주지 않고 실패한 고루틴만 로깅하기와 패닉, 한 번 더 패닉이다. 패닉과 에러에 대한 기초적인 내용은 다른 포스트에 적은 바 있다. Go: 에러와 패닉 (panic, recover) Go: 에러와 패닉 (panic, recover) 예외가 없다고? 그렇다. Go 언어에는 예외(Exception)가 없다. 에러로 모든 것을 처리한다. error 빌트인 타입은 존재하긴 하지만, 그렇다고 타언어처럼 모든 에러에 대해 타입이 매핑되어 있는 것은 pronist.tistory..

    Go: 웹 서버 구축하기 (net/http, html/template)

    WAS(Web Application Server) Node.js 서버처럼 Go 언어로 만든 서버도 동적 컨텐츠를 처리하는 WAS(Web Application Server)로써 동작하게 만들 수 있다. 보통 앞에 NginX, Apache 와 같은 범용적인 http 서버를 앞에다가 두고 뒤에 별도로 WAS 를 실행시켜두는 것이 일반적인 구성일 것이다. 물론 Go 로 만든 서버를 직접 80 포트에 바인딩하는 것도 가능하지만 요청이 많아질 경우 과부하가 걸릴 가능성도 있어서 많은 트래픽이 발생하는 경우에는 권장하는 방법은 아니다. 이 포스트에서 말하는 웹 서버는 Go 언어로 만든 서버를 의미할 것이며 이러한 서버를 만드는 행위는 Node.js http 모듈을 사용하여 만드는 것만큼 상당히 단순하다고 볼 수 있다..

    Go: Switch 를 사용하여 타입 체크하기 (Reflection) [Effective Go]

    일반적으로 다른 언어에서는 어떤 값의 타입에 따라 다른 행동을 하고 싶을 때 Reflection 를 사용하여 해결한다. Go 에서는 특이하게도 언어차원에서 Switch 를 사용하여 해결할 수 있는데, 다음과 같이 해볼 수 있다. var t interface{} = map[string]string{ "sayHello": "Hello, Go!", } switch t := t.(type) { case string: fmt.Println(t) case map[string]string: for k, v := range t { fmt.Println(k, v) } } Switch 와 함께 타입 단언(Type Assertion)을 사용하여 해결할 수 있다. 그런데 자세히 살펴보면 map 타입에 대해서는 상당히 불편한 ..

    Go: new vs make [Effective Go]

    Go 에는 메모리에 대한 것에 대해 유달리 헷갈리는 것들이 있는데, new, make, 그리고 포인터(Pointer)이다. C언어에서 동적 메모리를 할당할 때 쓰는 malloc, 초기화에 사용하는 memset 과는 달리 사용법이 다소 헷갈린다. 특히 Go 는 로컬 함수 스코프에서도 포인터를 반환하는 것을 허용하고 있기도 하므로 더욱 의문스럽다. new new() 는 메모리를 할당하되 초기화는 하지 않는다. 메모리를 할당하고 해당 객체에 제로(Zero Value)값을 설정하고 해당 객체에 대한 포인터를 반환하게 된다. Go 에서는 Zeroed Storage 라고 표현하는 듯하며 new() 를 사용하여 반환된 값은 포인터이고, 해당 포인터가 가리키는 값은 각 타입에 대한 제로값이다. m := new(MyTy..