STUDY/Go Lang

[GoLang] 가볍게 Go 입문하기 (1)

Jexists 2023. 10. 7. 00:33

[GoLang] — 가볍게 Go 입문하기 (1단계)

이 글은 골든래빗 《Tucker 의 Go 언어프로그래밍》의 1단계 써머리입니다.

목차

  1. Go 언어
  2. 변수
  3. fmt 패키지
  4. 연산자
  5. 함수
  6. 상수
  7. if문
  8. switch문
  9. for문

 


1. Go 언어

→ 2009년 발표된 오픈 소스 프로그래밍 언어

→ 2009년 11월 10일 발표

 

홈페이지: The Go Programming Language

온라인 컴파일러: Go Playground - The Go Programming Language

Hello World

package main

import "fmt"

func main() {
	fmt.Println("Hello World")
}

 


2. 변수

→ variable: 값을 저장하는 메모리 공간을 가리키는 이름

var 키워드 선언방식

  1. 선언하고 대입하는 방법
  2. 타입적지않고 쓰는 방법 (예상되는 타입일 경우 생략 가능)
  3. 타입적고 대입
  4. 한줄로 적는 방법
package main

func main() {
	// 1. 선언하고 대입하는 방법
	// var a = int
	// a = 4
	// 2. 타입적지않고 쓰는방법
	// var a = 4
	// 3. 타입적고 대입
	// var a int = 4
	// 4. 한줄로 적는 방법
	// a := 4
	// b := 2

	// 여러개 변수 선언
	// var a, b int = 10, 20
	// 여러개 제로값 할당
	// var a, b int
	// 여러개 다른 타입 변수 선언 가능
	// var a, b = 10, "hello"

	// 다양한 변수 한번에 선언 (선언리스트를 괄호 사용)
	// var (
	//  a int
	//  y = 20
	//  z int = 30
	//  d, e = 40, "hello"
	//  f, g string 
	// )

	// fmt.printf("%v\\n", a&b)
	// fmt.printf("%v\\n", a|b)
}

변수명 규칙

→ 문자, _, 숫자 사용가능 (첫글자: 문자 또는 _)

→ _ 제외한 특수문자 사용불가 (space 사용불가)

→ CamelCase 권장

 


3. fmt 패키지

3-1. 표준 출력 (Print, Println, Printf)

fmt.Print(): 줄바꿈없음
fmt.Println(): +\\n 자동줄바꿈 (개행)
fmt.Printf(): 서식문자

fmt.Print() vs fmt.Println()

fmt.Print("*")
fmt.Print("*")
//**

fmt.Println("*")
fmt.Println("*")
//*
//*

중요한 서식 문자

%t: boolean
%T: 데이터타입
%d: 정수
%s: 문자열
%f: 실수

특수문자

\\n: 줄바꿈
\\t: 탭 삽입
\\\\: \\ 출력
\\": " 출력

3-2. 표준 입력 (Scan, Scanln, Scanf)

Scan(): 공백과 개행으로 구분(엔터&띄어쓰기 구분)
Scanf(): 원하는 형태 & 지정한 형식
Scanln(): 공백으로 구분(띄어쓰기 구분)

예제)

package main

import (
	"fmt"
)

func main() {
	var a int
	var b int

	scan, err := fmt.Scan(&a, &b)
	if err != nil {
		fmt.Println(scan, err)
	} else {
		fmt.Println(scan, a, b)
	}

	var c int
	var d int
	scanf, err := fmt.Scanf("%d#%d\\n", &c, &d)
	if err != nil {
		fmt.Println(scanf, err)
	} else {
		fmt.Println(scanf, c, d)
	}

	var e int
	var f int
	scanln, err := fmt.Scanln(&e, &f)
	if err != nil {
		fmt.Println(scanln, err)
	} else {
		fmt.Println(scanln, e, f)
	}
	// 마지막 입력값 이후 엔터 키로 종료
}

 


4. 연산자

→ 각 항의 타입은 같아야함 (시프트 연산 예외)

→ 연산의 결과 타입도 같아야함

→ 대입 연산자는 결과 반환 안함 (a = b = 10 에러)

증감 연산자

// a값 1증가 시키는 3가지 방법
a = a + 1
a += 1
a++

[오류] b = a++ 
[오류] a++: 전위 증감 연산자 지원X

연산자 우선순위

- 좌측부터 우측으로 연산
1. * / % << >> & &^
2. + - | ^
3. == != < <= > >=
4. &&
5. ||

 


5. 함수

→ 함수 키워드: func 키워드 사용 함수 정의

→함수명: 함수명 (첫글자 대문자는 외부로 공개)

→ 함수 호출시 인수(입력받은 값)가 매개변수(함수에서 사용하는 값)에 복사되어 전달 (값 그대로 사용X)

→ 매개변수와 함수내에서 선언된 변수는 함수가 종료되면 변수 범위 벗어나서 접근 못함

→ 멀티반환함수: 여러개 반환가능 / 반환 타입을 소괄호() 묶어서 표현

→ 반환할 변수 변수명 지정해서 반환시 return에 해당 변수 안적어도됨

재귀호출 (recursive call)

→ 함수 안에서 자기 자신 함수 다시 호출

→ 탈출 조건 필수 (재귀 호출 종료 시점 필요 / 무한반복 방지)

package main

import "fmt"

func main() {
	printNo(3)
	// main() -> printNo(3) -> printNo(2) -> printNo(1) -> printNo(0) -> 탈출 -> 자신 호출한 위치로 차례대로 연속해서 다시 돌아감 -> 최초 호출 main()함수에 도착
	// 3
	// 2
	// 1
	// After 1
	// After 2
	// After 3
}

func printNo(n int) {
	if n == 0 {
		return
	}
	fmt.Println(n)
	printNo(n - 1)
	fmt.Println("After", n)
}

 


6. 상수

→ 변지 않는 값 (초기된 값)

iota

→ 1, 2, 3.. 처럼 1씩 증가하도록 정의할 때 사용

package main

import "fmt"

// 소괄호를 벗어나면 다시 초기화
func main() {
	const (
		Red   int = iota // 0
		Blue  int = iota // 1
		Green int = iota // 2
	)
	fmt.Println(Red)   // 0
	fmt.Println(Blue)  // 1
	fmt.Println(Green) // 2

	const (
		C1 uint = iota + 1 // 1 = 0 + 1
		C2                 // 2 = 1 + 1
		C3                 // 3 = 2 + 1
	)
	fmt.Println(C1) // 1
	fmt.Println(C2) // 2
	fmt.Println(C3) // 3
}

 


7. if문

package main

func main() {
	var 조건문 bool
	var 조건문1 bool
	var 조건문2 bool
	var 조건문3 bool

	if 조건문 {
		문장 // 조건문이 true일때 실행
	}

	if 조건문 {
		문장 // 조건문이 true일때 실행
	} else {
		문장 // 조건문이 false일때 실행
	}

	if 조건문1 {
		문장 // 조건문1이 true일때 실행
	} else if 조건문2 {
		문장 // 조건문2이 true일때 실행
	} else if 조건문3 {
		문장 // 조건문3이 true일때 실행
	} else {
		// else는 항상 맨 마지막 & 생략 가능
		문장 // 모든 조건 false일때 실행
	}

	// 초기문 먼저 실행 후 조건 검사
	if 초기문; 조건문 {
		문장 // 조건문이 true일때 실행
	}
}

 


8. switch문

switch 비교값 { // 검사하는 값
case 값1: // 비교값이 값1이 같을 때 실행
	문장
case 값2: // 비교값이 값2이 같을 때 실행
	문장
default: // 만족하는 case가 없을 때 실행 (생략 가능)
문장
}

### 하나의 case 한번에 여러값 비교
var day string
switch day {
case "monday", "tuesday", "wednesday", "thursday", "friday":
	fmt.Println("평일")
case "saturday", "sunday":
	fmt.Println("주말")
}

## 초기문
switch 초기문; 비교값 { // 초기문 먼저 실행되고 비교값 case들과 비교
case 값1: // 비교값이 값1이 같을 때 실행
	문장
case 값2: // 비교값이 값2이 같을 때 실행
	문장
default: // 만족하는 case가 없을 때 실행 (생략 가능)
	문장
}

break

→ break 사용 안해도 case하나 실행 후 자동으로 switch문 종료

fallthrough

→ case실행 후 다음 case까지 실행하고 싶을때 사용

i := 3

switch 비교값 {               
case 값1:
	문장 
	fallthrough // 값1 일치시 아래 case 모두 실행
case 값2:
	문장 // 실행
	fallthrough
case 값3:
	문장 // 실행
	fallthrough
case 값4:
	문장 // 실행, 마지막 case에는 fallthrough를 사용할 수 없음
}

 


9. for문

// 기본 반복문
for 초기문; 조건문; 후처리 {
  코드 블록 // 조건문이 true인 경우 수행
}

// 초기문 생략
// - 초기문 생략해도 ; 필수 (조건문 자리 표시)
for ; 조건문; 후처리 {
  코드 불록
}

// 후처리 생략
for 초기문; 조건문; {
  코드 블록
}

// 조건문만 있는 경우 (초기문&후처리 생략)
for ; 조건문; {
  코드 블록
}
for 조건문 {
  코드 블록
}

// 무한 루프
// - 조건문이 true이면 코드가 무한히 반복 (무한 반복문)
// - break사용해서 for문 종료 필요
for true {
  코드 블록
}
for {
  코드 블록
}

continue

  • 반복문 제어하는 키워드
  • 코드 블록을 수행하지 않고 곧바로 후처리이동

break

  • 반복문 제어하는 키워드
  • for문 종료
### 플래그 변수

→ 불리언 변수를 사용하는 것

→ 깃발처럼 올라갔는지 내려갔는지를 표시

func flagFor() { a := 1 b := 1 found := false for ; a <= 9; a++ { for b = 1; b <= 9; b++ { if ab == 45 { found = true break } } if found { break } } fmt.Printf("%d * %d = %d\n", a, b, ab) }

### 레이블

→ 레이블 정의 후 break할때 정의한 레이블 적어주면 그 레이블에 가장 먼저 속한 for문 모두 종료

func lableFor() {
	a := 1
	b := 1
OutterFor:
	for ; a <= 9; a++ {
		for b = 1; b <= 9; b++ {
			if a*b == 45 {
				break OutterFor
			}
		}
	}
	fmt.Printf("%d * %d = %d\\n", a, b, a*b)
}

 


나눠보고 싶은 이야기

  • 변수명 짓는 규칙 및 팁
  • if vs switch 선호하는 것