프로그래밍 언어/Golang

    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..

    Go: 싱글 바이너리로 웹 서비스 제공하기 (go-bindata)

    Go 를 사용하여 얻을 수 있는 이점 중 하나는, 빌드의 결과로 싱글 바이너리가 나와 간단하게 배포하고 사용자에게 제공할 수 있다는 점이다. 그런데, 이러한 Go 로 작성한 웹 서비스를 제공하려고 하다보면 각종 리소스 파일이 많아지는 것으로 인해 문제가 될 수 있다. 기껏 싱글 바이너리로 어플리케이션을 배포할 수 있는데 리소스 파일로 인해 배포할 파일이 늘어난다면 그건 이점을 살리지 못한 것이 될 지도 모른다. 리소스를 바이너리에 포함시키기 리소스를 별도의 파일로 분리시키지 않고 소스코드에 포함시켜 최종적으로는 바이너리에 포함될 수 있도록 만들 수 있는데, 바로 go-bindata 를 사용하면 그런 행위가 가능하다. go-bindata 를 사용하면 실제 파일시스템 경로와 유사한 사용방법으로 API 를 사..

    Go: 개발 환경과 도구, 크로스 컴파일

    환경변수 Go 를 사용하면서 알아두어야 할 일부 환경변수가 있는데, 알아보도록 하자. 콘솔에 go env 를 입력하면 아래와 같이 Go 에서 사용하는 환경변수 목록을 확인할 수 있다. 다 살펴볼 필요는 없지만, GOROOT, GOPATH, GOBIN, GOARCH, GOOS 정도는 알아두면 개발할 때 도움이 된다. 게다가 GOOS, GOAHCH 는 크로스 컴파일(Cross-Compile)을 할 때도 지정하는 환경변수이기도 하다. $ go env set GO111MODULE= set GOARCH=amd64 set GOBIN= set GOCACHE=C:\Users\user\AppData\Local\go-build set GOENV=C:\Users\user\AppData\Roaming\go\env set GO..

    Go: path vs path/filepath

    path vs path/filepath Go 에서 경로를 핸들링 할 수 있는 패키지에는 path, path/filepath 패키지가 있다. 이 둘은 쓰임새가 달라서 조심씨 사용하여야 하는데, 둘이 경로라는 대상을 다루지만, 실은 핸들링하는 대상이 다르다. 결론부터 말하자면 path 는 HTTP, FTP 경로 등 논리적인 경로를 핸들링한다, 즉 슬래쉬로 구분되는 경로에 대해서 다루며, 반면 path/filepath 패키지는 이름 그대로 실질적인 파일 경로를 취급하게 된다. Windows 같은 경우에는 C:\ 등으로 파일 경로가 시작되기도 하기 때문에 각별히 주의해야 할 필요가 있다. data/hello.txt 파일에는 Hello, Go! 라는 텍스트가 입력되어 있다고 가정하고, 아래의 코드를 살펴보자. 파..

    Go: flag 패키지로 CLI 도구 만들기

    flag Go 의 flag 패키지는 CLI(Command Line Interface) 어플리케이션을 작성하기 위해 사용하는 내장 패키지이다. 주로 서브 커맨드가 없는 싱글 커맨드에 대해 옵션을 지정하여 사용할 때 사용한다. 가장 간단한 사용법은 아래와 같다. 예를 들어 사용자에게 --port, --p 옵션을 통해 포트를 지정할 수 있는 옵션을 지정하여 값을 받는다고 생각해보자. package main import ( "flag" ) func main() { var port int flag.IntVar(&port, "port", 3000, "") flag.IntVar(&port, "p", 3000, "") flag.Parse() } 어플리케이션의 코드가 main.go 라고 가정해보면 다음과 같이 사용할 수..