안녕하세요, GDSC Ewha 고랭 스터디입니다 🥰
이번 주에는 저희 교재(Tucker의 Go 언어 프로그래밍, 공봉식 저)의 3,4,5장을 읽고, 정리하고 실습해봤습니다.
실습 코드는 해당 Github 브랜치에서 각 스터디원의 코드들을 확인하실 수 있습니다!
Chaper 0. Go 설치 및 환경 세팅
설치
https://golang.org/dl/ 에 접속해서 윈도우용 파일 다운로드,
다운로드한 설치 파일을 클릭하여 실행한다. > 이후 설치 진행
설치 확인
Go 확장 프로그램 설치
IDE는 VScode를 사용한다.
vscode에서 Go 프로그래밍을 할 수 있도록 도와주는 확장 프로그램을 설치해보자.
vscode에서 상단 메뉴 View>Extensions에 들어가,
검색창에 'Go' 입력 후
해당 익스텐션을 다운 받는다.
vscode 우측 하단에 뜨는 팝업창 > Install All 클릭.
output 창에 아래와 같은 문구가 뜨면 모든 환경 구축 완료.
코드 실행해보기
package main
import "fmt"
func main() {
fmt.Println("Hello Go World!")
//fmt.println("Hello Go World!")
}
Go 파일 실행 순서
cd (패키지명)
go mod init 프로젝트명/패키지명
go build
//실행하면 아래와 같이 .exe 파일이 생성된다..\hello.exe
// exe파일 실행
→ 성공!
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)
- (vscode) Terminal > New Terminal 에서 아래 명령어 입력
cd (폴더명)
go mod init 프로젝트명/폴더명
//모듈 생성go build
//실행하면 아래와 같이 .exe 파일이 생성된다.
.\hello.exe
// .exe파일 실행- → 성공!
📌 실행 원리 알아보기
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
→ 결과
📌 주의점 2: 큰 범위→작은 범위 타입 변환
큰 범위 → 작은 범위 타입 변환 시, 바이트 변화로 값이 전혀 달라질 수 있다.
ex. int16 → int8 로 변환할 때 상위 1바이트가 없어져 값이 변화
var typeBig int16 = 3456
var typeSmall int8 = int8(typeBig)
fmt.Println(typeBig)
fmt.Println(typeSmall)
→ 결과
변수의 범위: 전역 변수, 지역 변수
변수는 자신이 속한 중괄호 {} 범위를 벗어나면 사라진다.
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 파일 실행 명령어.
cd ottl
go mod init goproject/ottl
go build
.\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() 함수 사용법
- 최소 출력 너비 지정하기
- %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
- 소수점 이하 자릿수 지정하기
%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
- 특수 문자 사용하기
\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 개발자로 거듭나봅시다!!! ✨🤗
'3-1기 스터디 > Golang' 카테고리의 다른 글
[6주차] 숫자 맞추기 게임 만들기, Go 언어의 슬라이스 (0) | 2021.12.01 |
---|---|
[5주차] Chapter 15~16. 문자열, 패키지 (0) | 2021.11.30 |
[4주차] Go 언어의 배열, 구조체, 포인터 (0) | 2021.11.22 |
[3주차] Go언어의 if, switch, for (0) | 2021.11.11 |
[2주차] Go 언어의 연산자, 함수, 상수 (0) | 2021.11.03 |
댓글