go language 시작하기

설치하기

Go 는 패키지 매니저가 없으며 VCS에서 직접 받아와서 라이브러리를 사용합니다.

먼저, 다음 페이지에서 window 용 Go 를 설치해줍니다.

공식 다운로드 사이트

설치가 완료 되었다면. 아래와 같은 구조로 디렉터리를 만들어 줍니다.

Go/
  bin/
  pkg/
  src/

main.go 만들기

main.go

package main //namespace declaration 하는 부분으로 기능과 논리들을 그룹화시켜준다.

import "fmt" // format의 약자로 standard lib에 있다.

// 여기서 main 은 keyword 로써 해당 함수가 라이브러리가 아닌 어플리케이션으로 동작함을 나타낸다.
// go 어플리케이션이 여기서 시작된다.
// func는 function을 선언하는 keyword 이다.
func main() {
  fmt.Println("Hello, World") //여기서 println의 앞의 P가 대문자 인데, 이는 외부 라이브러리에서 가져왔음을 의미한다.
                              // 같은 원리로 함수를 선언할때 대문자로 시작하면 외부에서 접근이 가능한 것이다.
}

실행하기

go run main.go

빌드하기

go build # 실행가능한 binary 파일을 만들어 준다.
이 경우 파일명이 아니라 폴더 명으로 파일이 생성된다.
./go-study

윈도우용 빌드
GOOS=windows go build -o main.exe main.go

슬라이스

슬라이스는 배열의 값을 가리킵니다(point). 그리고 배열의 길이를 가지고 있습니다.

[]T 는 타입 T 를 가지는 요소의 슬라이스(slice) 입니다.

package main

import "fmt"

func main() {
    p := []int{2, 3, 5, 7, 11, 13}
    fmt.Println("p ==", p)

    for i := 0; i < len(p); i++ {
        fmt.Printf("p[%d] == %d\n",
            i, p[i])
    }
}

레인지

for 반복문에서 range 를 사용하면 슬라이스나 맵을 순회(iterates)할 수 있습니다.

package main

import "fmt"

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
    for i, v := range pow {
        fmt.Printf("2**%d = %d\n", i, v)
    }
}

_ 를 이용해서 인덱스(index)나 값(value)를 무시할 수 있습니다.

만약 인덱스만 필요하다면 “ , value ” 부분을 다 제거하면 됩니다.

package main

import "fmt"

func main() {
    pow := make([]int, 10)
    for i := range pow {
        pow[i] = 1 << uint(i)
    }
    for _, value := range pow {
        fmt.Printf("%d\n", value)
    }
}

맵은 값에 키를 지정합니다.

맵은 반드시 사용하기 전에 make 를 명시해야합니다. (주의: new 가 아닙니다)

make 를 수행하지 않은 nil 에는 값을 할당할 수 없습니다.

package main

import "fmt"

type Vertex struct {
    Lat, Long float64
}

var m map[string]Vertex

func main() {
    m = make(map[string]Vertex)
    m["Bell Labs"] = Vertex{
        40.68433, -74.39967,
    }
    fmt.Println(m["Bell Labs"])
}

맵 리터럴 (Map literals) 맵 리터럴은 구조체 리터럴과 비슷하지만 key 를 반드시 지정해야 합니다.

package main

import "fmt"

type Vertex struct {
    Lat, Long float64
}

var m = map[string]Vertex{
    "Bell Labs": Vertex{
        40.68433, -74.39967,
    },
    "Google": Vertex{
        37.42202, -122.08408,
    },
}

func main() {
    fmt.Println(m)
}

다양한 함수

package main

import "fmt"

func main() {
    m := make(map[string]int)

    m["Answer"] = 42
    fmt.Println("The value:", m["Answer"])

    m["Answer"] = 48
    fmt.Println("The value:", m["Answer"])

    delete(m, "Answer")
    fmt.Println("The value:", m["Answer"])

    v, ok := m["Answer"]
    fmt.Println("The value:", v, "Present?", ok)
}

switch

다른 일반적인 언어를 아는 분이라면 switch 에 대해서 잘 알 것입니다.

다른 언어와 다른점은 case의 코드 실행을 마치면 알아서 break를 한다는 점입니다.

( fallthrough 로 끝나는 case는 스스로 break를 하지 않습니다 )

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.", os)
    }
}

메소드

고에는 클래스가 없습니다. 하지만 메소드를 구조체(struct)에 붙일 수 있습니다.

메소드 리시버(method receiver) 는 func 키워드와 메소드의 이름 사이에 인자로 들어갑니다.

package main

import (
    "fmt"
    "math"
)

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := &Vertex{3, 4}
    fmt.Println(v.Abs())
}

인터페이스

인터페이스는 메소드의 집합으로 정의됩니다.

그 메소드들의 구현되어 있는 타입의 값은 모두 인터페이스 타입의 값이 될 수 있습니다.

package main

import (
    "fmt"
    "math"
)

type Abser interface {
    Abs() float64
}

func main() {
    var a Abser
    f := MyFloat(-math.Sqrt2)
    v := Vertex{3, 4}

    a = f  // a MyFloat implements Abser
    a = &v // a *Vertex implements Abser
    a = v  // a Vertex, does NOT
    // implement Abser

    fmt.Println(a.Abs())
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
    if f < 0 {
        return float64(-f)
    }
    return float64(f)
}

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)