[ Go ] Go 언어 기본 문법 (1)

 
by 박신종

GoLang

Go는 2009년 구글이 개발한 트렌디한 언어로, 빠른 성능과 상대적으로 간결한 문법을 사용하기 때문에 배우는데 오랜시간이 걸리지 않는다고 합니다.

Go언어의 특징은 다음시간에 알아보도록 하고 어떻게 사용 할 수 있는지 사용법에 대해서 설명하도록 하겠습니다.




패키지 (Packages)

모든 Go 프로그램은 패키지로 구성되어 있습니다.

프로그램은 main 패키지에서부터 실행을 시작합니다.

이 프로그램은 "fmt""math" 패키지를 import 해서 사용하고 있습니다.

패키지 이름은 디렉토리 경로의 마지막 이름을 사용하는 것이 규칙입니다.

예를 들어 "path/filepath" 를 사용한다면 패키지명은 filepath 입니다

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println("Happy", math.Pi, "Day")
}



임포트 (import)

이 코드에서는 여러개의 "package" 를 소괄호로 감싸서 import를 표현합니다. 아래와 같이 import 문장을 여러번 사용할 수 도 있습니다.

import "fmt"
import "math"



익스포트 (Exported names)

패키지를 Import 하면 패키지가 외부로 export 한 것들(메서드나 변수, 상수 등)에 접근할 수 있습니다.

Go에서는 첫 문자가 대문자로 시작하면 그 패키지를 사용하는 곳에서 접근할 수 있는 exported name이 됩니다.

예를 들어 FooFOO 는 외부에서 참조할 수 있지만 foo 는 참조 할 수 없습니다.

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println(math.Pi)
}



함수 (1)

함수는 매개변수(인자)를 가질 수 있습니다.

예를 들어 add 라는 함수는 두개의 int 타입 매개변수를 받습니다.

C, C++, Java 언어와 다르게 매개변수의 타입은 변수명 뒤에 명시합니다.

func add(x int, y int) int {
    return x + y
}

func main() {
    fmt.Println(add(42, 13))
}



함수 (2)

두 개 이상의 매개변수가 같은 타입(type)일 때, 같은 타입을 취하는 마지막 매개변수에만 타입을 명시하고 나머지는 생략할 수 있습니다.

예를 들어

x int, y int

과 같은 문장은 아래와 같이 표현할 수 있습니다.

x, y int


func add(x, y int) int {
    return x + y
}

func main() {
    fmt.Println(add(42, 13))
}



여러 개의 결과 (Multiple results)

하나의 함수는 여러 개의 결과를 반환할 수 있습니다.

예제 코드에서의 함수는 두개의 문자열을 반환합니다.

func swap(x, y string) (string, string) {
    return y, x
}

func main() {
    a, b := swap("hello", "world")
    fmt.Println(a, b)
}



이름이 정해진 결과 (Named results)

함수는 매개변수를 취합니다. Go에서 함수는 여러 개의 결과를 반환할 수 있습니다. 반환 값에 이름을 부여하면 변수처럼 사용할 수도 있습니다.

결과에 이름을 붙히면, 반환 값을 지정하지 않은 return 문장으로 결과의 현재 값을 알아서 반환합니다.

func split(sum int) (x, y int) {
    x = sum * 4 / 9
    y = sum - x
    return
}

func main() {
    fmt.Println(split(17))
}



변수 (Variables)

변수를 선언을 위해 var 을 사용합니다.

함수의 매개변수처럼 타입은 문장 끝에 명시합니다.

var x, y, z int
var c, python, java bool

func main() {
    fmt.Println(x, y, z, c, python, java)
}



변수의 초기화

변수 선언과 함께 변수 각각을 초기화를 할 수 있습니다.

초기화를 하는 경우 타입(type)을 생략할 수 있습니다. 변수는 초기화 하고자 하는 값에 따라 타입이 결정됩니다.

var x, y, z int = 1, 2, 3
var c, python, java = true, false, "no!"

func main() {
    fmt.Println(x, y, z, c, python, java)
}



변수의 짧은 선언

함수 내에서 := 을 사용하면 var 과 명시적인 타입(e.g. int, bool) 을 생략할 수 있습니다.

(그러나 함수 밖에서는 := 선언을 사용할 수 없습니다.)

func main() {
    var x, y, z int = 1, 2, 3
    c, python, java := true, false, "no!"

    fmt.Println(x, y, z, c, python, java)
}



상수 (Constants)

상수는 const 키워드와 함께 변수처럼 선언합니다.

상수는 문자(character), 문자열(string), 부울(boolean), 숫자 타입 중의 하나가 될 수 있습니다.

const Pi = 3.14

func main() {
    const World = "안녕"
    fmt.Println("Hello", World)
    fmt.Println("Happy", Pi, "Day")

    const Truth = true
    fmt.Println("Go rules?", Truth)
}



숫자형 상수

숫자형 상수는 정밀한 값(values) 을 표현할 수 있습니다.

타입을 지정하지 않은 상수는 문맥(context)에 따라 타입을 가지게 됩니다.

코드를 통해 needInt(Big) 는 어떤 결과를 출력할지 실험해보세요.

const (
    Big   = 1 << 100
    Small = Big >> 99
)

func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
    return x * 0.1
}

func main() {
    fmt.Println(needInt(Small))
    fmt.Println(needFloat(Small))
    fmt.Println(needFloat(Big))
}

#21
#0.2
#1.2676506002282295e+29



For문 활용 (1)

Go 언어에서는 반복문이 for문밖에 없습니다.

기본적인 for 반복문은 C와 Java 언어와 거의 유사합니다.

다른점은 소괄호 “( )”를 사용하지 않습니다.

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



For문 활용 (2)

C와 Java에서 처럼 조건문만 표현할 수도 있습니다.

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



Go 에서 “While” 사용하기

C언어에서 while을 사용하듯이 for을 사용할 수 있습니다.

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



무한루프

func main() {
    for {
    }
}



조건문 If

if 문은 C와 Java와 비슷합니다. 조건 표현식을 위해 소괄호”( )” 는 사용하지 않습니다.

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



if와 짧은 명령어 사용하기

if 문의 조건문 앞에서 짧은 문장을 실행할 수 있습니다.

func pow(x, n, lim float64) float64 {
    if v := math.Pow(x, n); v < lim {
        return v
    }
    return lim
}

짧은 실행문을 통해 선언된 변수는 if문 안쪽에서만 사용할 수 있습니다.

if와 else

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