본문 바로가기
  • GDG on campus Ewha Tech Blog
3-1기 스터디/Golang

[1주차] Go 언어 입문하기 (개념, 변수, 표준입출력, 설치 방법)

by 융서융서 2021. 10. 13.

안녕하세요, GDSC Ewha 고랭 스터디입니다 🥰
이번 주에는 저희 교재(Tucker의 Go 언어 프로그래밍, 공봉식 저)의 3,4,5장을 읽고, 정리하고 실습해봤습니다.
실습 코드는 해당 Github 브랜치에서 각 스터디원의 코드들을 확인하실 수 있습니다!


Chaper 0. Go 설치 및 환경 세팅

설치

https://golang.org/dl/ 에 접속해서 윈도우용 파일 다운로드,

Untitled

다운로드한 설치 파일을 클릭하여 실행한다. > 이후 설치 진행

Untitled 1

설치 확인

Untitled 2

Go 확장 프로그램 설치

IDE는 VScode를 사용한다.

vscode에서 Go 프로그래밍을 할 수 있도록 도와주는 확장 프로그램을 설치해보자.

vscode에서 상단 메뉴 View>Extensions에 들어가,
검색창에 'Go' 입력 후

해당 익스텐션을 다운 받는다.

Untitled 3

vscode 우측 하단에 뜨는 팝업창 > Install All 클릭.

output 창에 아래와 같은 문구가 뜨면 모든 환경 구축 완료.

Untitled 4


코드 실행해보기

package main

import "fmt"

func main() {
    fmt.Println("Hello Go World!")
        //fmt.println("Hello Go World!")
}

Go 파일 실행 순서

  1. cd (패키지명)
  2. go mod init 프로젝트명/패키지명
  3. go build //실행하면 아래와 같이 .exe 파일이 생성된다.
  4. .\hello.exe // exe파일 실행

Untitled 6

성공!

Untitled 7


Chapter3. Hello Go World

3.1 Go 소개

📌 역사

  • 2009년 구글에서 만든 오픈소스 프로그래밍 언어이다.
  • → 누구나 내부 구조를 살펴볼 수 있고, 언어 발전에 이바지 가능.
  • Go, Golang, 고랭 등 다양하게 불린다.

📌 장점

  • 심플한 문법 구조를 가지고 있다.
  • 적은 코딩으로 빠르고 강력한 성능을 낼 수 있다.
  • 개발자가 사랑하는 언어 5위.
  • 미국에서 3번째로 많은 연봉을 받는 인기 언어.

📌 어디에 쓰이는가

  • 백엔드 서버와 시스템 개발에 적합하고 강력한 동시성 프로그래밍을 지원한다.

3.2 Go 언어의 특징

( O )

  • 메서드
  • 인터페이스
  • 익명 함수
  • 가비지 컬렉터
  • 포인터

( X )

  • 클래스
  • 상속
  • 제네릭 프로그래밍
  • 네임스페이스 → 모든 코드는 패키지 단위로 분리된다.

3.3 Go 코딩

코드 실행 시 Go는 이런 과정을 거칩니다.

Go 모듈 생성 > 빌드 (.exe 파일 생성) > 실행

📌 Go 파일 실행 방법 (Terminal)

  1. (vscode) Terminal > New Terminal 에서 아래 명령어 입력
  2. cd (폴더명)
  3. go mod init 프로젝트명/폴더명 //모듈 생성
  4. go build //실행하면 아래와 같이 .exe 파일이 생성된다.

Untitled 6

  1. .\hello.exe // .exe파일 실행
  2. 성공!

Untitled 7


📌 실행 원리 알아보기

1) cd hello

2) go mod init goproject/hello 명령으로 모듈을 생성한다.

모든 Go 코드는 빌드하기 전에 모듈을 생성해야 한다!
→ go.mod 파일이 goproject/hello 폴더 내에 생성됨.
→ go.mod 파일에는 모듈명, Go 버전, 필요한 패키지 목록 정보가 담겨 있음.

3) go build 로 빌드

Go 코드를 기계어로 변환하여 실행 파일을 만든다.
이때, 실행파일에 대한 설정을 GOOS와 GOARCH 환경변수를 이용해 바꿀 수 있다.
ex) `GOOS=linux GOARCH=amd64 go build` → AMD64 계열의 리눅스 실행 파일 만들기

4) .\hello.exe 로 실행


📌 Hello Go World 코드 뜯어보기

코드 한 줄 한 줄이 의미하는 바를 알아보자.

package main   //1

import "fmt"   //2

func main() {  //3
    fmt.Println("Hello Go World!")   //4
}

1) package main → Go언어의 모든 코드는 반드시 패키지 선언으로 시작해야 한다.

main 패키지에 속한 코드라고 컴파일러에게 알려준다.
main 패키지는 "프로젝트 시작점이 있는 패키지다."

main() 함수가 없는 패키지는 패키지 이름으로 main을 쓸 수 없다.
프로그램은 항상 main() 함수에서 시작되고, main() 함수가 종료되면 프로그램도 종료된다.
즉, 프로그램 시작과 끝이 main() 함수이므로,
패키지 이름으로 main을 쓰는 **package main**은 프로그램 시작점이 있는 패키지이다.

2) import "fmt" → 표준입출력을 다루는 fmt 패키지를 불러온다.

3) func main() { } → main() 함수는 프로그램 진입점 함수!

4) fmt.Println("Hello Go World") → Hello Go World를 터미널 화면에 출력합니다. (표준 출력)


Chapter4. 변수 Variable

4.1 변수 선언

  • 변수란? : 값을 저장하는 메모리 공간
  • 변수 선언 방법
    • var a int = 10
    • var b int // 초깃값 생략 (기본값으로 대체)
    • var c = 4 // 타입 생략 (우변 값의 타입이 됨)
    • d := 10 // 선언 대입문 :=을 사용해서 var 키워드와 타입 생략
  • 변수의 원리

var minimumWage int = 10 처럼 변수를 선언하면,

1) 메모리에 저장할 공간을 만들고, (int만큼)

2) minimumWage 라고 지칭한 뒤,

3) 값 10을 복사한다.

→ 이제 minimumWage 라는 변수명을 이용해서 해당 공간에 접근할 수 있다.

4.2 변수 특징

📌 타입별 기본값

  • 모든 정수 타입(int, uint, byte, rune, int8, uint64등등)은 0
  • 모든 실수 타입(float32, float64, complex64등등)은 0.0
  • 불리언은 false 가 기본값,
  • 문자열은 "" (빈 문자열)
  • 그 외에는 nil (정의되지 않은 메모리주소를 나타내는 Go 키워드) 로 기본값이 설정된다.
  • (거의 다른 언어의 기본값과 비슷하다!!)

📌 기본 타입

타입 생략 시, 우변의 타입으로 변수 타입이 자동 지정됨.

  • 정수 값의 기본 타입은 int
  • 실수 값의 기본 타입은 float64
var b = 3  //b의 타입은 int
var c = 0.001  //c의 타입은 float64

4.3 타입 변환과 주의점

Go는 최강 타입 언어이다! → 

융통성이 매우 없다는 뜻

쉽게 말해, 연산이나 대입에서 타입이 다르면 에러가 발생한다.

심지어 int와 int64 값 사이 호환도 안 된다 → 개발자가 하나하나 타입 변환을 해줘야 함

var a int
var b int64 = 3
a = b  // ERROR. a는 int타입, b는 int64타입이므로 대입연산 불가.

var c float64 = 3.5
d := a*c  // 당연히 ERROR. a는 int, c는 float형이므로 연산 불가.

다른 언어에서는 자동으로 변환해주는 타입들도 Go는 지원하지 않는다.

→ 개발자가 직접 타입 변환 해줘야 한다.

a = int(b)
d := float64(a) * c

원하는 타입명을 적고 ( )로 변수를 묶어준다.


📌 주의점 1: 실수→정수 타입 변환

실수 → 정수 타입으로 변환하면, 소수점 이하 숫자가 없어진다.

a := 3.5
var b int = int(a * 3) // b= int(10.5) = 10
var c int = int(a) * 3 // c= 3*3 = 9
var isEqual bool = (b == c) // 두 값이 같은가

fmt.Println(isEqual) // false
fmt.Println(b, c)  // 10 9

→ 결과

Untitled (1)

📌 주의점 2: 큰 범위→작은 범위 타입 변환

큰 범위 → 작은 범위 타입 변환 시, 바이트 변화로 값이 전혀 달라질 수 있다.

ex. int16 → int8 로 변환할 때 상위 1바이트가 없어져 값이 변화

var typeBig int16 = 3456
var typeSmall int8 = int8(typeBig)

fmt.Println(typeBig)
fmt.Println(typeSmall)

→ 결과

Untitled (2)


변수의 범위: 전역 변수, 지역 변수

변수는 자신이 속한 중괄호 {} 범위를 벗어나면 사라진다.

package main

import "fmt"

var g int = 10 //global variable

func main() {
    var m int = 20 //local variable
    {
        var s int = 50 //local variable in {}
        fmt.Println(m, s, g)

    } // variable 's' dead

    fmt.Println(m, g)  // 20 10
    fmt.Println(s)  // ERROR
}

이쯤에서 다시 짚어보는 Go 파일 실행 명령어.

  1. cd ottl
  2. go mod init goproject/ottl
  3. go build
  4. .\ottl.exe

Chapter5. fmt 패키지를 이용한 표준 입출력

📌 fmt 패키지

표준 입출력 기능을 제공하는 Go 언어 기본 패키지

import "fmt"

4.1 표준 출력 Print()

📌 Print(), Println(), Printf() 함수 비교

  • Print() → 출력
  • Println() → 출력하고 개행
  • Printf() → 서식(format)에 맞도록 출력 (%d, %f, %s 등 이용)
    var a int = 10
    var b int = 20
    var f float64 = 123456789.9876

    fmt.Print("a:", a, "b:", b)
    fmt.Println("a:", a, "b:", b, "f:", f)
    fmt.Printf("a: %d b: %d f: %f\n", a, b, f)

→ 결과

a:10b:20a: 10 b: 20 f: 1.234567899876e+08
a: 10 b: 20 f: 123456789.987600

여기서 주목할 점은, Println() 함수로 f값을 출력했을 때와 Printf() 함수로 출력했을 때 형태가 다르다는 점이다.

Println() 함수로 실수 출력 시, %f가 아니라 %g 서식으로 출력되므로, 값이 지수 형태로 출력된다.

📌 Printf() 함수 사용하기

Printf(서식 문자열, 인수1, 인수2, ...)

서식 문자 종류: %d, %f, %s, %v

※ 서식 문자 **%v**를 이용하면 모든 타입의 기본 서식으로 출력한다.

→ Printf() 함수 사용법

  1. 최소 출력 너비 지정하기
    • %5d(최소 5칸을 이용해서 채움)
    • %05d(빈칸은 0으로 채움)
    • %-5d(왼쪽 정렬)
      	var a = 123
      	var b = 456
      	var c = 123456789
      
      	fmt.Printf("%5d, %5d\n", a, b)    // %5d
      	fmt.Printf("%05d, %05d\n", a, b)  // %05d
      	fmt.Printf("%-5d, %-05d\n", a, b) // %-5d (왼쪽 정렬)
      
      	// 지정한 최소 너비보다 긴 값일 경우
      	fmt.Printf("%5d\n", c)
      	fmt.Printf("%05d\n", c)
      
      /* 결과 */
      123,   456
      00123, 00456
      123  , 456
      123456789
      123456789​
  2. 소수점 이하 자릿수 지정하기
    • %f
    • %g (실수를 정수부와 소수점 이하 숫자를 포함해 출력 숫자를 제한한다) → 나머지는 지수 표현으로 전환함.
    • %8.5f (최소 너비 8로 채우고, 소수점 이하는 5자리만 표현)
    • %8.5g (최소 너비 8로 채우고, 총 숫자를 5자리로 제한)
      	var a = 123.12345
      	var b = 3.14
      
      	// %f와 %g 차이 비교
      	fmt.Printf("%08.2f\n", a) //최소 너비 8, 소수점 이하 2자리, 공백은 0으로 채움
      	fmt.Printf("%08.2g\n", a) //최소 너비 8, 총 숫자 2자리, 공백은 0으로 채움
      
      	fmt.Printf("%8.5g\n", a) //최소 너비 8, 총 숫자 5자리
      	fmt.Printf("%f\n", b) // 기본값==소수점 이하 6자리까지 출력
      
      /* 결과 */
      00123.12
      01.2e+02
        123.12
      3.140000​
  3. 특수 문자 사용하기
  • \n → 줄바꿈
  • \t → 탭
  • \\ → \ 자체를 출력한다.
  • \" → 따옴표 출력

4.2 표준 입력 Scan()

Scan() 함수는 fmt.Scan(&a) 형태로 변수 a에 값을 입력받고, 성공적으로 입력한 값 개수(n)와 입력 실패 시 에러(err)를 반환한다.

바로 예제를 살펴보자.

    var a int
    var b int

    n, err := fmt.Scan(&a, &b) // n과 err에 입력 두 값 받기
    if err != nil {            // 실패한 경우
        fmt.Println(n, err)
    } else {                   // 성공한 경우
        fmt.Println(n, a, b)
    }

→ 결과

/* 정상 입력 시 */
100 300  //내가 입력한 값
2 100 300  // n=2 대입되고, 입력값이 a,b에 성공적으로 저장됨

/* 비정상 입력 시 */
300 String //b에 정수가 아니라 문자열을 입력
1 expected integer  //입력된 값 1개

📌 Scan(), Scanln(), Scanf() 함수 비교

  • Scan() → 입력
  • Scanln() → 한 줄을 읽어서 입력 받음
  • Scanf() → 서식(format) 형태로 값을 입력 받음

Scanf() 함수

fmt.Scanf("%d %d\n", &a, &b)

a와 b 사이 공란 하나, 한줄 띄우기에 맞춰진 입력을 받음

→ 서식 맞추기 힘들기 때문에, Scan() 또는 Scanln() 함수를 권장.

Scanln() 함수

fmt.Scanf("%d %d\n", &a, &b)

마지막 입력값 이후 반드시 엔터키로 입력을 종료해야 한다는 점이 다르다.


여기까지,

고랭 스터디의 첫 포스팅이었습니다!

앞으로도 열심히 공부해서, GO 개발자로 거듭나봅시다!!! ✨🤗

고랭 스터디의 야심찬 Goal ✨✨

댓글