본문 바로가기

golang

golang3 변수와 상수

변수

golang의 변수선언 방법은 2가지다.

1. var 변수명 타입

golang에서 변수 1개를 선언하는 방법이다. 타입은 생략 가능하다. 하지만 타입을 생략할 경우 초기값을 반드시 삽입해주어야 한다.(nil제외)

var variableName int

매우 간단한 방법이다. 다른 언어에서도 이러한 선언 방식을 보았을 것이다. 이 선언 방식을 Variable A is string, 즉 변수 A는 string이다 로 읽히므로 코드를 좀 더 이해하기 쉽다는 말도 있다.

var num1=10
var num2 int=10

위의 두 방식은 모두 같은 타입을 가진 변수 선언코드이다.

2. short assignment statement

변수 선언과 동시에 초기화를 시키는 방법이다. 위의 방법과의 차이점이라면 var 예약어와 타입을 접두와 접미에 붙일 필요 없이 변수명만으로 선언과 초기화가 가능하다. 이 방식은 변수만 선언 가능하고 상수는 선언할 수 없다.

num1:=10
num2:=20

3. 다중 선언

여러개의 변수를 선언시킬 수 있다. 1번과 2번 방식으로 모두 가능하다. 타 언어에서도 이 기능을 접해보았을 것이다. 사용은 다음과 같다.

package main

import "fmt"

func main() {
	num1, num2, num3, str1 := 1, 2, 3, "a"
	var num4, str2 = 10, "b"
	var num5, num6 int8 = 127, 127

	fmt.Println(num1, num2)
	fmt.Println(num3, str1)
	fmt.Println(num4, str2)
	fmt.Println(num5, num6)
}

실행결과는 다음과 같다.

다중 변수 선언 및 초기화

1번 방식이든 2번 방식이든 모두 변수 선언 및 초기화가 가능하다. 또한 여러개의 변수 타입을 1개로 지정하여 선언 및 초기화를 할 수도 있다.(num5,num6)

golang변수의 특징

golang을 사용할 때 다른 언어와의 차이점이 있다. 이는 다음과 같다.

1. 미사용 변수가 존재할 시 컴파일 수행중 에러를 반환한다.

golang에서는 쓸데없이 메모리를 차지하는 것에 대해 매우 싫어한다. 그래서 사용하지 않는 변수에 대해선 에러를 반환한다. 다음의 코드를 보자

package main

func main() {
	num1, num2, num3, str1 := 1, 2, 3, "a"
}

단순히 변수를 선언 및 초기화만 진행하였다. 실행결과는 다음과 같다.

에러

변수들이 선언되었지만 사용되지 않았다는 에러를 반환하며 컴파일과정에서 종료한다. 이 기능이 존재하므로 개발 과정에서 무분별하게 변수를 선언하여 사용하는 것을 방지할 수 있다.

2. 변수 초기값(zero value)

golang은 변수에 초기값을 지정하지 않았을 때 기본값으로 초기화를 해준다. 이를 golang에선 zero value라고 부른다.

golang의 zero value는 다음과 같다.

  • 숫자 타입(정수): 0
  • 숫자 타입(실수, 복소수): 0.0
  • 문자(문자, 문자열): ""
  • boolean: false
  • 함수, 포인터, map, slice, 채널: nil

상수

golang 상수는 const 키워드를 통해 선언된다.

const c=10

물론 다중 선언도 가능하다.

const str1, str2 = "a", "b"

여러개의 상수를 괄호를 통해 선언할 수 있다. 만약 초기값이 없으면 이전 상수의 초기값을 이용하여 상수를 선언 및 초기화를 수행한다.

func main() {
	const (
		n1 = "a"
		n2
		n3 = iota
		n4
		n5
	)
	fmt.Println("iota : ", n1, n2, n3, n4, n5)
}

실행결과는 다음과 같다.

상수선언

괄호로 선언할 경우 값이 초기화가 되어있지 않으면 직전 상수의 값으로 상수를 초기화한다.

위의 코드와 실행결과에서 특이한 것이 보일 것이다. 변수 1개가 iota로 선언되어있는데 값이 2부터 순차적으로 선언되었다. iota가 뭘까?

iota

iota는 괄호로 묶여있는 상수 선언문에서만 사용 가능하다.

초기값이 설정되어 있지 상수를 iota가 선언된 상수번째부터 int형 정수를 오름차순으로 초기화를 수행한다.

다음의 코드를 보자

package main

import "fmt"

func main() {
	const (
		n1 = iota
		n2
		n3
		n4
		n5
	)
	const (
		t1 = "test"
		t2
		t3 = iota
		t4 = "wa"
		t5 = "ha"
		t6
		t7 = 12.5
		t8 = iota
		t9
		t10 = 130
		t11 = iota
		t12
		t13
	)
	fmt.Println("iota : ", n1, n2, n3, n4, n5)
	fmt.Println(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13)
}

실행결과는 다음과 같다.

iota예제

위의 상수가 다음과 같이 초기화가 된 이유는 다음과 같다.

  1. n1~n5

    n1은 1번째로 선언된 상수이므로 0으로 초기화가 수행된다. 그리고 이후의 n2~n5까지 오름차순으로 초기화를 수행하여 1,2,3,4 로 초기화가 수행되었다.

  2. t2

    t2는 작성된 초기값이 없으므로 직전 상수의 초기값인 test로 초기화를 수행하였다.

  3. t3 t3은 3번째로 초기화된 상수이므로 2로 초기화가 수행된다.

  4. t4~t6

    t4, t5까지 별도의 초기값이 존재하므로 t3에서 선언한 iota가 적용되지 않는다.

    t6은 직전 상수인 t5의 초기값으로 상수를 초기화를 수행한다.

  5. t8, t9

    iota가 선언된 t8은 8번째로 선언된 값이므로 7를 초기값으로 수행하여 t9까지 오름차룬으로 초기화

  6. t10~t13

    t10에서 정수 130으로 초기화를 수행하였어도 t11부터 iota에 영향을 미치지 않으므로 10~12로 오름차순으로 초기화

이 문법은 어떻게 쓰일까? 여러 방법이 있지만 필자가 생각하는 방법은 enum으로 사용하는 방법이다. 다음의 코드를 보자

package main

import "fmt"

func main() {
	const (
		INVALID_INPUT = iota
		INVALID_TOKEN_LENGTH
	)
	var token string
	_, err := fmt.Scanf("%s", &token)
	if err != nil {
		panic(fmt.Sprintf("errorcode %d", INVALID_INPUT))
	}
	if len(token) != 16 {
		panic(fmt.Sprintf("errorcode %d", INVALID_TOKEN_LENGTH))
	} else {
		fmt.Println("hello world")
	}
}

token을 입력받는 매우 간단한 코드다. 로직은 다음과 같다.

  1. 토큰을 입력받는다.
  2. 입력과정에서 오류가 발생 여부를 확인한다.
  3. token의 길이가 16임을 확인한다.
  4. 이전 과정에서 문제가 없었으면 hello world 문장을 출력한다.

위의 코드에서 INVALID_INPUT과 INVALID_TOKEN_LENGTH는 enum처럼 해당 오류가 발생한 원인에 대해 서술한다.

상수의 제약사항

  • golang은 모든 타입을 상수로 만들어서 사용할 수 없다.
  • 상수선언이 가능한 타입
    • bool
    • rune
    • int
    • float
    • complex
    • string int,float,complex는 크기가 다른 타입(int32, int64등)도 포함이다.

Reference

golang constants

'golang' 카테고리의 다른 글

golang7 slice  (0) 2022.01.09
golang6 구조체  (0) 2021.12.26
golang5 조건문과 반복문  (0) 2021.12.25
golang4 함수  (0) 2021.12.24
golang1 연산자  (0) 2021.12.19