프로그램 전체입니다. Run을 눌러 보세요.
이 중 생략할 수 있는 줄은 없습니다. 이 페이지의 나머지 부분에서 각 줄이 하는 일을 설명합니다.
한 줄씩 보기
package main
모든 Go 파일은 자신이 속한 패키지 이름을 적는 package 절로 시작합니다. main이라는 이름은 특별해서, 이 패키지가 실행 가능한 프로그램임을 나타냅니다. 다른 이름(package utils, package hello)을 쓰면 다른 코드가 가져다 쓰는 라이브러리가 되고, 혼자서는 실행할 수 없습니다.
import "fmt"
import는 다른 패키지를 가져와 쓸 수 있게 합니다. fmt는 표준 라이브러리의 형식화 및 출력 패키지입니다. import한 뒤에는 패키지 이름을 통해 공개된 이름에 접근합니다: fmt.Println, fmt.Printf, fmt.Sprintf.
여러 패키지를 가져오려면 괄호 블록에 경로를 한 줄에 하나씩 씁니다:
import (
"fmt"
"strings"
)
Go는 사용하지 않는 패키지를 import한 파일을 컴파일하지 않습니다. 덕분에 의존성 목록이 정직하게 유지되고, 대부분의 사람이 처음 만나는 오류도 바로 이것입니다.
func main()
func는 함수를 선언합니다. main 패키지의 main이 진입점입니다. 프로그램은 main이 시작할 때 시작하고 main이 반환할 때 끝납니다. 인자를 받지 않고 아무것도 반환하지 않습니다. 명령줄 인자는 os.Args에서, 종료 코드는 os.Exit로 다룹니다.
fmt.Println("Hello, World!")
Println은 인자를 출력하면서 사이에 공백을 넣고 끝에 줄바꿈을 붙입니다. 이름이 대문자로 시작하는 이유는 대문자로 시작하는 이름만 패키지 밖으로 공개되기 때문입니다. 소문자 p로 쓴 fmt.println은 컴파일 오류입니다.
문자열 말고 다른 값 출력하기
Println은 어떤 타입의 값이든 개수에 상관없이 받습니다. Printf를 쓰면 형식을 직접 정할 수 있습니다:
%s는 문자열로, %d는 정수로 바뀝니다. Printf와 Print는 줄바꿈을 붙이지 않으므로 \n을 직접 써야 합니다. 전체 동사(verb) 표는 fmt.Printf 페이지에 있습니다.
내 컴퓨터에서 실행하기
Go를 설치했다면 빈 폴더에 프로그램을 main.go로 저장하고 실행합니다:
go run main.go
Hello, World!
go run은 파일을 임시 바이너리로 컴파일한 뒤 실행합니다. 보관하거나 다른 곳에 복사할 수 있는 바이너리를 만들려면 go build를 씁니다:
go mod init example.com/hello
go build
./hello
Hello, World!
go build에는 모듈(go.mod 파일)이 필요하고, 이 파일은 go mod init이 만듭니다. 바이너리 이름은 모듈 경로의 마지막 부분을 따르며, 여기서는 hello입니다(Windows에서는 hello.exe). run, build, install의 차이는 go run과 go build 페이지에서 다룹니다.
세미콜론은 어디로 갔을까
Go 문법은 세미콜론을 쓰지만 직접 입력할 일은 거의 없습니다. 컴파일러는 마지막 토큰이 문장을 끝낼 수 있는 줄의 끝에 세미콜론을 넣습니다. 식별자, 리터럴, ), }, 그리고 return 같은 몇몇 키워드가 여기에 해당합니다. 다른 언어에서 흔한 다음 스타일이 실패하는 이유가 이 규칙입니다:
func main()
{
fmt.Println("Hello, World!")
}
./main.go:6:1: syntax error: unexpected semicolon or newline before {
func main() 뒤에 세미콜론이 들어갔으므로 다음 줄의 {는 오류가 됩니다. 여는 중괄호는 항상 같은 줄에 둡니다. if, for, switch를 비롯한 모든 블록에 같은 규칙이 적용됩니다.
처음 만나는 오류 해설
초보자가 처음 한 시간 안에 보게 되는 메시지들을 Go 1.24가 출력하는 그대로 옮겼습니다.
사용하지 않는 import나 변수.
package main
import (
"fmt"
"os"
)
func main() {
x := 5
fmt.Println("hi")
}
./main.go:5:2: "os" imported and not used
./main.go:9:2: declared and not used: x
둘 다 경고가 아니라 컴파일 오류입니다. import나 변수를 지우세요. 디버깅하는 동안 변수를 남겨 둬야 한다면 빈 식별자에 대입합니다: _ = x.
소문자 함수 이름.
./main.go:6:6: undefined: fmt.println
공개되지 않은 이름은 패키지 밖에서 보이지 않습니다. fmt.Println을 쓰세요.
잘못된 패키지 이름.
package example.com/hello is not a main package
파일에 package hello(또는 main이 아닌 다른 이름)라고 적혀 있는데 실행하려고 한 경우입니다. package main으로 바꾸세요.
모듈이 없음.
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
go build와 go run .은 모듈 단위로 동작합니다. 폴더에서 go mod init example.com/hello를 한 번 실행하세요. 파일 이름을 지정하는 go run main.go는 모듈 없이도 동작합니다.
포매팅
Go에는 공식 코드 스타일이 하나 있고, gofmt가 그 스타일을 적용합니다. 작성하는 모든 파일에 실행하세요:
go fmt ./...
들여쓰기에 탭을 쓰고, 주석과 구조체 필드를 정렬하며, 공백을 정규화합니다. Go를 지원하는 에디터는 저장할 때 자동으로 실행합니다. 어디서든 Go 코드가 같은 모양이므로 설정할 것도, 코드 리뷰에서 논쟁할 것도 없습니다.
자주 묻는 질문
Go로 hello world는 어떻게 작성하나요?
다음 내용을 main.go로 저장합니다:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
그리고 go run main.go를 실행하면 Hello, World!가 출력됩니다.
Go 프로그램에 package main이 왜 필요한가요?
package main은 이 패키지가 라이브러리가 아니라 실행 가능한 프로그램이라고 컴파일러에 알려 줍니다. 프로그램은 main 패키지의 main 함수에서 시작합니다. 다른 패키지 이름을 쓰면 라이브러리가 되고, go run은 "is not a main package"라며 실행을 거부합니다.
Go에서는 왜 여는 중괄호를 같은 줄에 써야 하나요?
Go는 문장이 끝날 수 있는 줄의 끝에 세미콜론을 자동으로 넣고, func main() 뒤도 여기에 해당합니다. 그러면 다음 줄의 {는 별도의 블록을 시작하게 되어 컴파일러가 syntax error: unexpected semicolon or newline before {를 보고합니다. 중괄호는 반드시 같은 줄에 둬야 합니다.
Go에서 fmt는 무슨 뜻인가요?
fmt는 형식화된 입출력을 담당하는 표준 라이브러리 패키지입니다(이름은 "format"의 줄임말). fmt.Println은 인자 사이에 공백을 넣고 끝에 줄바꿈을 붙여 출력하고, fmt.Printf는 형식 문자열을 써서 출력합니다.