Go를 배워보자 1일차 - GO의 기본 구조와 변수, 타입

1

Go

목록 보기
1/12

Go? GO!

1. Go는 무엇이며? 왜 배워야할까??

필자는 4G/5G 통신 서버 개발자라 속도에 민감해 c/c++만을 사용한다. 그런데 요즘들어 여러 통신 서버 개발자 분들이 golang을 사용하는 것을 보았고 좋아보여서 공부해보려고 한다.

사실 필자도 잘모르겠다. 그냥 로고가 귀여워서 공부하려고한다.

힙찔이

2. 어떻게 다운받으면 될까?

https://golang.org/dl/

여기에 들어가서 자신의 플랫폼에 맞는 다운로드 파일을 설치하면 된다.
금방 설치되서 아주 좋다.

3. hello world 출력해보기

개발자들 대부분이 하는 말 중에 그 언어의 "hello world"까지 해보았다면 절반은 아는 것이다. 라는 띵언이 있다.

물론 이 말에 죽자고 달려드는 -찐- 들도 있지만, '시작이 반이다' 라는 속담처럼 개발자들 사이의 속담으로 생각하면 된다.

먼저 main.go 파일을 만들어보도록 하자

main.go

package main

import "fmt"

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

그럼 실행을 해보자 터미널에서 다음의 명령어를 입력하면 된다.

go run main.go

다음의 결과가 나올 것이다.

Hello World

Go의 기본 코드를 분석하면 코드 구조를 쉽게 알 수 있다.

  1. package : 현재 파일이 어떤 패키지에 속하는 지를 알려준다.
  2. import : 어떤 코드에서 다른 패키지에 있는 코드를 사용하기 위해 패키지를 가져오는 것이다.
  3. func main() {} : c/c++, java의 main함수와 같은 entry point 역할을 한다. API 함수의 경우는 굳이 main을 만들 필요는 없지만, 구동이 필요하다면 main이 있어야 한다.
  4. fmt.Println() : fmt는 format이라는 의미로 "fmt" 패키지에 있다. 이를 통해 서식 문자로 출력이 가능하다.

결국 정리하자면 Go 파일은 3가지 부분으로 나눌 수 있다.

1. package 절
2. import 문
3. 코드

참고로 golang은 js처럼 세미콜론(;)을 써도되고 안써도된다. 물론 써주는게 가독성 측면에서 좋다.

재미있는 것은 golang은 실제 참조하는 package만 가져오려고 한다는 것이다. 만약 vscode에서 extension을 깔아놓고 쓸 떼 fmt.Println() 함수를 지워보자, 그러면 자동으로 import의 "fmt"로 사라진다.

이는 "fmt"가 안쓰였기 때문이다.

4. import문으로 다른 패키지의 함수 사용하기

굉장히 단순하다

package main

import (
	"math"
	"strings"
)

func main() {
	math.Floor(2.75)
	strings.Title("hello")
}

가져오려는 package들을 import() 안에 콤마(,)없이 "" 로 하나씩 써주면 된다.

여기서 조심해야할 것은 go는 c/c++처럼 ''와 ""을 구분하므로 잘 알아두자

5. Go의 타입들

Go는 정적 타입언어이다. js처럼 동적으로 선언한 타입이 변하지 않는다. 그렇기 때문에 basic type은 꽤나 중요하다.
Go의 Basic Type들은 꽤나 c/c++과 닮았다. 정리하면 다음과 같다.

  1. 정수형 : int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uinptr
  2. 바이트 : byte 라고 쓰지만 내부적으로 uint8과 같다.
  3. 문자 : '' 로 표현하며 rune 이라고 표현한다. 내부적으로 int32와 같다.
  4. 문자열 : ""로 표현하며 string 으로 쓴다.
  5. 실수형 : float32, float64
  6. boolean : bool
  7. 복소수 : complex64, complex128

특이한 점을 짚어보자

  1. 문자(rune) vs 문자열
    rune은 '룬'이라고 읽고 보통 우리가 생각하는 문자와 같다. 따라서 '' 로 표현한다.
    우리가 생각하는 문자와 같기 때문에 이 역시 내부적으로 유니코드를 가리키고 있어 rune을 출력하면 숫자가 나온다.
package main

import (
    "fmt"
)

func main() {
	fmt.Println('c') // 99
}

문자열은 "" 으로 표현한다. 재밌는 것은 문자열 string의 각 값들을 출력하면 rune과 같이 출력된다.

package main

import (
	"fmt"
)

func main() {
	var str string = "cibal"
	fmt.Println('c') // 99
	fmt.Println(str[0]) // 99
}

그러나 c/c++ 처럼 string의 각 요소들을 변경할 수는 없다. 자바처럼 str[0] = 'w'로 접근하면 에러가 발생한다.

  1. complex
    복소수형을 지원한다는데, 사실 써본 적이 없어서 묵혀두었다가 나중에 보자

6. 변수 선언하기

Go에서 변수란 값을 가지고 있는 저장소이다. 변수 선언을 통해 변수에 이름을 부여할 수 있다.

재미있게도 var 이라는 키워드를 사용하는데 정적 타입 언어이다!

var 변수이름 타입 = 값

매우 희안한 구조를 가지고 있다.
typescript나 kotlin과 엇비슷하면서도 다르다.
아래는 typescript의 변수 선언이다.

let variable : string = "typescript"

golang은 다음과 같다.

var variable string = "go"

변수를 만들었으니 사용해보자

package main

import "fmt"

func main() {
	var variable string = "go"
	fmt.Print(variable) // go
}

아 추가적으로 golang은 절대절대 한 번도 사용되지 않는 변수가 존재하는 것을 허용을 해주지 않는다.

즉, 변수를 만들었다면 반드시 어느 곳에서 한 번이라도 쓰여야 살아남는다. 아니면 컴파일 에러가 난다. 대부분의 언어에서는 warning이 발생하는데 아주 깐깐하다.

6.1 디폴트

변수 선언 시 값을 초기화해주 읺으면 다음의 디폴트 값이 들어간다.

  1. 정수, 실수 : 0
  2. 문자열 : 빈 문자열("")
  3. bool : false
package main

import "fmt"

func main() {
	var str string
	var boolean bool
	var digit int
	var sosu float32
	fmt.Println(str) // 
	fmt.Println(boolean) // false
	fmt.Println(digit) // 0
	fmt.Println(sosu) // 0
}

6.2 단축 변수 선언

이거 참 기가막히다. 처음보는 사람들은 기절초풍할 문법이라서 눈이 휘둥글해진다.

변수를 선언할 때 선언과 동시에 값을 할당하는 경우에는 보통 "단축 변수 선언"을 사용한다. 변수의 타입을 명시적으로 선언하고, 나중에 값을 할당하는 대신 := 연산자를 이용하여 선언과 초기화 작업을 동시에 하는 것이다.

package main

import "fmt"

func main() {
	quantity := 4
	length, width := 1.2, 2.4
	customerName := "su lee"
	fmt.Println(quantity) // 4
	fmt.Println(length, width) // 1.2 2.4
	fmt.Println(customerName) // su lee
}

자동으로 들어가는 값에 따라 타입을 정해준다. 따라서 만약 다른 타입의 값을 넣으려고 한다면 에러가 발생하게 된다.
맨 처음에는 어색하지만 좀 쓰다보면 이렇게 편할 수가 없다.

6.3 네이밍 규칙

GO에는 함수, 변수, 타입을 명명하는데 간단한 규칙들이 있다.
1. 이름은 문자로 시작해야하며, 임의 개수와 문자와 숫자로만 구성한다.
2. 변수 , 함수, 타입의 이름이 대문자로 시작하면 노출되어 외부 패키지에서 접근할 수 있다. 그래서 fmt의 Println이 앞이 대문자인 것이다. 반면에 소문자로 적시할 시에는 외부로 노출되지 않는다.

6.4 타입 변환

Go에서는 수학 및 비교 연산에는 동일한 타입의 값만 사용할 수 있다. 따라서 타입이 다른 경우에는 에러가 발생한다.

따라서, float32와 int를 비교하거나, string과 int를 비교하면 에러가 발생한다.

package main

import "fmt"

func main() {
	quantity := 4
	length := 1.2
	fmt.Println(quantity * length) // invalid operation: mismatched types int and 
}

또한, 변수의 타입이 다른 값을 할당하려고 하면 에러가 발생한다. 때문에 타입 변환이 필요한 것이다.

타입 변환 방법은 매우 간단한데

바꾸려는타입(변수) 

이다.

package main

import (
	"fmt"
	"reflect"
)

func main() {
	quantity := 4
	length := 1.2
	fmt.Println(quantity * int(length))
	fmt.Println(float64(quantity) * length)
	fmt.Println(reflect.TypeOf(quantity))
	fmt.Println(reflect.TypeOf(float64(quantity)))
}

reflect.TypeOf(변수)를 통해서 변수의 타입도 알 수 있다. 중요한 것은 이렇게 타입 변환 시에는 변수의 타입 자체를 바꾸는 것이 아니라, 타입을 바꾼 결과를 리턴한다는 것을 알아두자

따라서 float64(quantity) 를 한 번했음에도 quantity는 int형이 나오는 이유가 바로 그것이다.

또한, 실수형을 정수로 바꾸면 여타 다른 언어와 마찬가지로 소수부가 사라지는 내림 현상을 사용한다.

참고로 정수형, 실수형끼리 크기 비교도 안된다.

package main

import (
	"fmt"
)

func main() {
	quantity := 4
	length := 1.2
	fmt.Print(quantity < length)
}

에러가 발생할 것이다.

오늘은 여기까지만 맛보기를 하고 뒤에서 더 자세히 알아보도록 하자

0개의 댓글