본문 바로가기

SW LAB/Go Lang

[Google Go 언어] 모듈 생성 및 Build, Install

External Package Import

  1. 패키지는 다음 주소에서 검색 `https://pkg.go.dev/`
  2. hello.go 의 코드 다음과 같이 수정
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
  1. `go mod tidy` 명령어로 package 설치 프로젝트 Root 경로에 `go.sum` 파일이 추가됨
  2. `go run .` 으로 실행 `Don't communicate by sharing memory, share memory by communicating.` 출력 확인

Create Module And Import

  1. greetings 패키지 생성 및 코드 작성 이름이 주어지지 않을 경우 Error 정보를 전달
package greetings

import (
	"errors"
	"fmt"
)

// Hello returns a greeting for the named person.
func Hello(name string) (string, error) {
	// If no name was given, return an error with a message.
	if name == "" {
		return "", errors.New("empty name")
	}

	// If a name was received, return a value that embeds the name
	// in a greeting message.
	message := fmt.Sprintf("Hi, %v. Welcome!", name)
	return message, nil
}
  1. hello 패키지 생성 및 모듈 호출
package main

import (
	"fmt"
	"log"

	"example.com/greetings"
)

func main() {
	// Set properties of the predefined Logger, including
	// the log entry prefix and a flag to disable printing
	// the time, source file, and line number.
	log.SetPrefix("greetings: ")
	log.SetFlags(0)

	// Request a greeting message.
	message, err := greetings.Hello("")
	// If an error was returned, print it to the console and
	// exit the program.
	if err != nil {
		log.Fatal(err)
	}

	// If no error was returned, print the returned message
	// to the console.
	fmt.Println(message)
}
  1. 코드를 실행하기 전에 hello 패키지에서 `go mod tidy` 를 호출하여 greetings 의 종속성을 갖춰야 함

random 활용 코드

  1. 다음과 같이 코드 작성
  • init() 은 자동으로 호출되는 함수
  • randomFormat() 호출 시 3가지의 문자열 중 랜덤으로 하나 반환
package greetings

import (
	"errors"
	"fmt"
	"math/rand"
	"time"
)

// Hello returns a greeting for the named person.
func Hello(name string) (string, error) {
	// If no name was given, return an error with a message.
	if name == "" {
		return name, errors.New("empty name")
	}
	// Create a message using a random format.
	message := fmt.Sprintf(randomFormat(), name)
	return message, nil
}

// init sets initial values for variables used in the function.
func init() {
	rand.Seed(time.Now().UnixNano())
}

// randomFormat returns one of a set of greeting messages. The returned
// message is selected at random.
func randomFormat() string {
	// A slice of message formats.
	formats := []string{
		"Hi, %v. Welcome!",
		"Great to see you, %v!",
		"Hail, %v! Well met!",
	}

	// Return a randomly selected message format by specifying
	// a random index for the slice of formats.
	return formats[rand.Intn(len(formats))]
}

map 과 for 활용 코드

  • Hellos(names []string) 함수는 배열 string 값을 받을 수 있음 그리고 map 데이터 반환
  • make(map[string]string) 는 string 형의 키([string])과 string 형의 값(string) 을 생성한다는 의미
  • for := range 는 index 와 value 를 반환하는 반복문을 의미
package greetings

import (
	"errors"
	"fmt"
	"math/rand"
	"time"
)

// Hello returns a greeting for the named person.
func Hello(name string) (string, error) {
	// If no name was given, return an error with a message.
	if name == "" {
		return name, errors.New("empty name")
	}
	// Create a message using a random format.
	message := fmt.Sprintf(randomFormat(), name)
	return message, nil
}

// Hellos returns a map that associates each of the named people
// with a greeting message.
func Hellos(names []string) (map[string]string, error) {
	// A map to associate names with messages.
	messages := make(map[string]string)
	// Loop through the received slice of names, calling
	// the Hello function to get a message for each name.
	for _, name := range names {
		message, err := Hello(name)
		if err != nil {
			return nil, err
		}
		// In the map, associate the retrieved message with
		// the name.
		messages[name] = message
	}
	return messages, nil
}

// Init sets initial values for variables used in the function.
func init() {
	rand.Seed(time.Now().UnixNano())
}

// randomFormat returns one of a set of greeting messages. The returned
// message is selected at random.
func randomFormat() string {
	// A slice of message formats.
	formats := []string{
		"Hi, %v. Welcome!",
		"Great to see you, %v!",
		"Hail, %v! Well met!",
	}

	// Return one of the message formats selected at random.
	return formats[rand.Intn(len(formats))]
}
  • 호출 시 결과는 다음과 같이 출력 `map[Darrin:Hi, Darrin. Welcome! Gladys:Hi, Gladys. Welcome! Samantha:Hail, Samantha! Well met!]`

Test Module

  • go 파일명의 postfix 로 `_test` 를 넣으면 유닛 테스트를 수행할 수 있음
  • `greetings_test.go` 파일을 생성 후 다음 코드 작성
  • `go test` 를 수행하면 테스트 수행 (`go test -v` 하면 상세 내용 출력)|
package greetings

import (
	"regexp"
	"testing"
)

// TestHelloName calls greetings.Hello with a name, checking
// for a valid return value.
func TestHelloName(t *testing.T) {
	name := "Gladys"
	want := regexp.MustCompile(`\b` + name + `\b`)
	msg, err := Hello("Gladys")
	if !want.MatchString(msg) || err != nil {
		t.Fatalf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want)
	}
}

// TestHelloEmpty calls greetings.Hello with an empty string,
// checking for an error.
func TestHelloEmpty(t *testing.T) {
	msg, err := Hello("")
	if msg != "" || err == nil {
		t.Fatalf(`Hello("") = %q, %v, want "", error`, msg, err)
	}
}

go build

  • `go build` 는 종속성을 포함하여 패키지를 생성하지만, 결과는 설치하지 않음 즉, 실행하기 위해서 파일이 있는 위치로 가야 함
  • `go install` 는 패키지를 생성하요 설치까지 수행, 어디서든 실행 가능
  1. `hello` 패키지에서(main이 있는) `go build` 를 입력하면 `hello.exe` 파일을 생성 실행하면 정상적으로 실행하여 결과를 출력하는 것을 확인할 수 있음 `go list -f '{{.Target}}'` 를 입력하면 파일의 위치 확인 가능

go intall

  • install을 할 경우 설치되는 위치를 환경변수로 지정해야 함
  • 그리고 `go install` 수행 시 설정된 위치에 설치 후 어디서나 호출 가능
  1. 다음과 같이 환경 변수 지정 `set PATH=%PATH%;"C:\workspace\go\isntall\directory"` (windows) `export PATH=$PATH:/home/kjham/go/install/directory` (linux)
  2. `go install` 수행
  3. 그리고 아무 곳에서나 `hello` 호출 시 실행 된 것을 확인 가능