변수는 프로그래밍의 중요한 개념으로 마스터하는 것이 중요합니다. 변수는 프로그램에서 사용하는 값을 대신하는 기호입니다.
이 튜토리얼에서는 변수의 기본 사항과 Go 프로그램에서 변수를 사용하기 위한 모범 사례를 다룰 것입니다.
변수 이해하기
기술적인 용어로, 변수는 기호 이름이나 식별자에 연결된 값에 저장 위치를 할당하는 것입니다. 우리는 변수 이름을 사용하여 컴퓨터 프로그램 내에서 해당 저장된 값을 참조합니다.
변수를 값에 묶인 이름이 있는 라벨로 생각할 수 있습니다.
예를 들어 정수 1032049348
이 있고 이를 반복해서 긴 숫자를 다시 입력하는 대신 변수에 저장하려고 합니다. 이를 위해 기억하기 쉬운 이름을 사용할 수 있습니다. 예를 들어 변수 i
를 사용합니다. 변수에 값을 저장하기 위해 다음과 같은 구문을 사용합니다:
이 변수를 값에 묶인 라벨로 생각할 수 있습니다.
라벨에는 변수 이름 i
가 적혀 있고, 정수 값 1032049348
에 묶여 있습니다.
구문 i := 1032049348
은 몇 가지 부분으로 구성된 선언 및 할당 문장입니다:
- 변수 이름 (
i
) - 단축 변수 선언 할당 (
:=
) - 변수 이름(
1032049348
)에 할당되는 값 - Go에 의해 추론된 데이터 타입(
int
)
다음 섹션에서 타입을 명시적으로 설정하는 방법을 살펴보겠습니다.
이 모든 부분이 함께 변수 i
를 정수 1032049348
의 값과 동일하게 설정하는 문장을 구성합니다.
변수에 값을 할당하는 즉시 해당 변수를 초기화하거나 생성합니다. 이 작업을 마치면 값 대신 변수를 사용할 준비가 된 것입니다.
i
를 1032049348
의 값과 동일하게 설정한 후에는 정수 대신 i
를 사용할 수 있으므로 출력해 봅시다:
Output1032049348
변수를 사용하여 빠르고 쉽게 수학 연산을 할 수도 있습니다. i := 1032049348
을 사용하여 다음 구문으로 정수 값 813
을 뺄 수 있습니다:
Output1032048535
이 예제에서 Go는 수학 연산을 수행하여 변수 i
에서 813을 빼서 합계 1032048535
를 반환합니다.
수학에 관해 언급하자면, 변수는 수학 방정식의 결과와 동일하게 설정될 수 있습니다. 두 숫자를 더하고 그 합계의 값을 변수 x
에 저장할 수도 있습니다:
이 예제가 대수학과 유사하게 보일 수 있다는 점에 주목하십시오. 공식과 방정식 내에서 숫자와 양을 나타내기 위해 문자와 기호를 사용하는 것처럼 변수는 데이터 타입의 값을 나타내는 상징적인 이름입니다. Go 구문을 올바르게 하려면 변수가 방정식의 왼쪽에 있는지 확인해야 합니다.
이제 x
를 출력해 봅시다:
Output221
Go가 221
값을 반환한 이유는 변수 x
가 76
과 145
의 합계와 같게 설정되었기 때문입니다.
변수는 정수뿐만 아니라 모든 데이터 유형을 나타낼 수 있습니다:
이러한 변수 중 하나를 인쇄하면 Go는 해당 변수와 동일한 것을 반환합니다. 문자열 slice
데이터 유형에 대한 할당 문을 사용해 보겠습니다:
Output[one two three]
우리는 []string{"one", "two", "three"}
의 슬라이스 값을 변수 slice
에 할당한 다음 fmt.Println
함수를 사용하여 slice
를 호출하여 해당 값을 출력했습니다.
변수는 컴퓨터 내에서 지정된 값을 허용하는 작은 메모리 영역을 확보하여 해당 공간과 연결되는 방식으로 작동합니다.
변수 선언
Go에서는 여러 가지 방법으로 변수를 선언할 수 있으며, 경우에 따라 정확히 동일한 변수와 값을 선언할 수 있는 방법이 두 가지 이상 있습니다.
우리는 초기화 없이 int
데이터 유형의 i
라는 변수를 선언할 수 있습니다. 즉, 값을 넣을 공간을 선언하지만 초기 값은 지정하지 않습니다:
이렇게 하면 int
데이터 유형의 i
로 선언된 변수가 생성됩니다.
우리는 다음과 같은 예제에서처럼 등호(=
) 연산자를 사용하여 값을 초기화할 수 있습니다:
Go에서 이러한 두 가지 선언 형식을 긴 변수 선언이라고 합니다.
또한 짧은 변수 선언을 사용할 수도 있습니다:
이 경우, i
라는 변수와 int
데이터 타입이 있습니다. 데이터 타입을 지정하지 않으면 Go가 데이터 타입을 추론합니다.
변수를 선언하는 세 가지 방법으로, Go 커뮤니티는 다음과 같은 관용구를 채택했습니다:
-
변수를 초기화하지 않을 때만 긴 형식,
var i int
를 사용하세요. -
선언과 동시에 초기화할 때는 짧은 형식,
i := 1
을 사용하세요. -
Go가 데이터 타입을 추론하지 않길 원하지만 짧은 변수 선언을 사용하려면, 다음 구문과 같이 원하는 타입으로 값을 감싸면 됩니다:
값을 초기화할 때 긴 변수 선언 형식을 사용하는 것은 Go에서 관용적이지 않습니다:
다른 사람들이 프로그램을 원활하게 읽을 수 있도록 Go 커뮤니티가 일반적으로 변수를 선언하는 방식을 따르는 것이 좋습니다.
제로 값
모든 내장 타입은 제로 값을 가지고 있습니다. 할당된 모든 변수는 값이 할당되지 않았더라도 사용할 수 있습니다. 다음 타입들의 제로 값을 확인할 수 있습니다:
Outputvar a int = 0
var b string = ""
var c float64 = 0
var d bool = false
우리는 fmt.Printf
구문에서 %T
동사를 사용했습니다. 이는 함수에게 변수의 데이터 타입
을 출력하도록 지시합니다.
Go에서는 모든 값이 제로
값을 가지고 있기 때문에 다른 언어들처럼 정의되지 않은
값을 가질 수 없습니다. 예를 들어, 어떤 언어에서는 불리언
이 정의되지 않음
, 참
, 또는 거짓
일 수 있어 변수에 세 가지
상태를 허용합니다. Go에서는 불리언 값에 대해 두 가지
이상의 상태를 가질 수 없습니다.
변수 명명: 규칙 및 스타일
변수의 명명은 상당히 유연하지만, 염두에 두어야 할 몇 가지 규칙이 있습니다:
- 변수 이름은 단 하나의 단어로만 구성되어야 합니다(즉, 공백이 없어야 함).
- 변수 이름은 문자, 숫자, 밑줄(
_
)로만 구성되어야 합니다. - 변수 이름은 숫자로 시작할 수 없습니다.
이러한 규칙을 따라, 유효한 변수명과 유효하지 않은 변수명을 모두 살펴보겠습니다:
Valid | Invalid | Why Invalid |
---|---|---|
userName |
user-name |
Hyphens are not permitted |
name4 |
4name |
Cannot begin with a number |
user |
$user |
Cannot use symbols |
userName |
user name |
Cannot be more than one word |
또한, 변수명을 지을 때 대소문자를 구분한다는 점을 염두에 두십시오. 이러한 이름들 userName
, USERNAME
, UserName
, uSERnAME
는 모두 완전히 다른 변수입니다. 프로그램 내에서 유사한 변수명을 사용하지 않는 것이 가장 좋은 방법입니다. 이를 통해 현재와 미래의 협력자들과 함께 변수를 명확하게 유지할 수 있습니다.
변수는 대소문자를 구분하지만, Go에서 변수의 첫 글자의 대소문자는 특별한 의미를 가집니다. 변수가 대문자로 시작하면, 해당 변수는 선언된 패키지 외부에서 접근 가능합니다(또는 exported
). 변수가 소문자로 시작하면, 선언된 패키지 내에서만 사용할 수 있습니다.
Email
은 대문자로 시작하므로 다른 패키지에서 접근할 수 있습니다. password
는 소문자로 시작하므로, 선언된 패키지 내에서만 접근 가능합니다.
Go에서는 매우 간결한(또는 짧은) 변수명을 사용하는 것이 일반적입니다. userName
과 user
중 하나를 변수로 사용할 경우, user
를 선택하는 것이 관용적입니다.
또한 변수명의 간결함은 범위와도 관련이 있습니다. 변수가 존재하는 범위가 작을수록 변수명도 작아야 합니다.
우리는 변수 names
를 더 큰 범위에서 사용하므로, 프로그램에서 그것이 무엇을 의미하는지 기억하는 데 도움이 되는 더 의미 있는 이름을 지어주는 것이 일반적입니다. 그러나 i
와 n
변수는 바로 다음 줄에서 사용된 후 다시 사용되지 않습니다… 이러한 이유로, 코드를 읽는 사람이 변수가 어디에 사용되는지 또는 그 의미가 무엇인지 혼란스러워하지 않을 것입니다.
다음으로, 변수 스타일에 대한 몇 가지 주의사항을 살펴보겠습니다. 스타일은 여러 단어로 된 이름에 대해 밑줄 대신 MixedCaps
또는 mixedCaps
를 사용하는 것입니다.
Conventional Style | Unconventional Style | Why Unconventional |
---|---|---|
userName |
user_name |
Underscores are not conventional |
i |
index |
prefer i over index as it is shorter |
serveHTTP |
serveHttp |
acronyms should be capitalized |
스타일에 관한 가장 중요한 점은 일관성을 유지하고, 팀이 그 스타일에 동의하는 것입니다.
변수 재할당
‘변수’라는 단어가 암시하듯이, 우리는 Go 변수를 쉽게 변경할 수 있습니다. 이는 이전에 할당된 변수에 다른 값을 연결할 수 있음을 의미합니다. 재할당이 가능하다는 것은 프로그램 과정에서 이미 초기화된 변수에 사용자가 생성한 값을 받아들여야 할 수도 있고, 이전에 정의된 것에 대한 할당을 변경해야 할 수도 있기 때문에 유용합니다.
이미 정의된 변수가 무엇인지 명확하지 않은 다른 사람이 작성한 대규모 프로그램을 작업할 때, 변수를 쉽게 재할당할 수 있다는 것을 아는 것이 유용할 수 있습니다.
int
타입의 i
라는 변수에 76
값을 할당한 다음, 42
라는 새로운 값을 할당해 봅시다:
Output76
42
이 예제는 먼저 변수 i
에 정수 값을 할당한 다음, 이번에는 42
값을 할당하여 변수 i
를 재할당할 수 있음을 보여줍니다.
참고: 변수를 선언하고 초기화할 때는 :=
를 사용할 수 있지만, 이미 선언된 변수의 값을 단순히 변경하려면 등호 연산자(=
)만 사용하면 됩니다.
Go는 타입이 지정된
언어이므로 한 타입을 다른 타입에 할당할 수 없습니다. 예를 들어, int
타입의 변수에 "Sammy"
값을 할당할 수 없습니다:
서로 다른 타입을 서로 할당하려고 하면 컴파일 시간 오류가 발생합니다:
Outputcannot use "Sammy" (type string) as type int in assignment
Go에서는 변수 이름을 두 번 이상 사용할 수 없습니다:
Outputs redeclared in this block
동일한 변수 이름에 대해 짧은 변수 선언을 두 번 이상 사용하려고 하면 컴파일 오류가 발생할 수도 있습니다. 이는 실수로 인해 발생할 수 있으므로 오류 메시지가 무엇을 의미하는지 이해하는 것이 도움이 됩니다:
Outputno new variables on left side of :=
변수 선언과 마찬가지로 변수 이름을 신중하게 지정하면 나중에 다시 살펴볼 때 프로그램의 가독성을 높여줄 수 있습니다.
다중 할당
Go는 또한 한 줄에 여러 값을 여러 변수에 할당할 수 있게 해줍니다. 이러한 각 값은 서로 다른 데이터 타입일 수 있습니다:
Outputshark
2.05
15
이 예제에서 변수 j
는 문자열 "shark"
에 할당되었고, 변수 k
는 부동 소수점 2.05
에 할당되었으며, 변수 l
는 정수 15
에 할당되었습니다.
이러한 방식으로 한 줄에 여러 변수에 여러 값을 할당하면 코드의 줄 수를 줄일 수 있습니다. 하지만 코드의 가독성을 해치지 않는 것이 중요합니다.
전역 및 지역 변수
프로그램 내에서 변수를 사용할 때는 변수 범위를 염두에 두어야 합니다. 변수의 범위는 특정 프로그램의 코드 내에서 해당 변수에 접근할 수 있는 특정 위치를 나타냅니다. 즉, 모든 변수가 특정 프로그램의 모든 부분에서 접근 가능한 것은 아닙니다. 일부 변수는 전역 변수가 되고 일부는 지역 변수가 될 것입니다.
전역 변수는 함수 외부에 존재합니다. 지역 변수는 함수 내부에 존재합니다.
전역 및 지역 변수의 동작을 살펴보겠습니다:
Outputlocal
global
여기서 우리는 var g = "global"
을 사용하여 함수 외부에 전역 변수를 생성합니다. 그런 다음 printLocal()
함수를 정의합니다. 함수 내부에서 l
이라는 지역 변수가 할당되고 출력됩니다. 프로그램은 printLocal()
을 호출한 후 전역 변수 g
를 출력하며 끝납니다.
g
가 전역 변수이기 때문에 printLocal()
에서 참조할 수 있습니다. 이전 프로그램을 수정하여 그렇게 해보겠습니다:
Outputlocal
global
global
먼저 전역 변수 g
를 선언하고, var g = "global"
입니다. main
함수에서 printLocal
함수를 호출하면, 지역 변수 l
을 선언하고 출력합니다, fmt.Println(l)
. 그런 다음 printLocal
은 전역 변수 g
를 출력합니다, fmt.Println(g)
. g
가 printLocal
내에서 정의되지 않았지만, 전역 범위에서 선언되었기 때문에 여전히 접근할 수 있습니다. 마지막으로 main
함수도 g
를 출력합니다.
이제 함수 외부에서 지역 변수를 호출해 보겠습니다:
Outputundefined: l
지역 변수는 할당된 함수 외부에서 사용할 수 없습니다. 그렇게 하려고 하면 컴파일 시 undefined
오류가 발생합니다.
전역 변수와 지역 변수에 동일한 변수 이름을 사용하는 또 다른 예제를 살펴보겠습니다:
Output10
7
5
이 프로그램에서 우리는 num1
변수를 두 번 선언했습니다. 처음에는 전역 범위에서 num1
을 선언했고, var num1 = 5
, 그리고 printNumbers
함수의 지역 범위 내에서 다시 num1 := 10
으로 선언했습니다. main
프로그램에서 num1
을 출력하면 값 5
가 출력됩니다. 이는 main
이 전역 변수 선언만 볼 수 있기 때문입니다. 하지만 printNumbers
함수에서 num1
을 출력하면 지역 선언을 보게 되어 값 10
이 출력됩니다. printNumbers
가 num1
이라는 새 변수를 생성하고 값 10
을 할당했지만, 이는 값 5
를 가진 전역 num1
인스턴스에 영향을 주지 않습니다.
변수 작업을 할 때, 프로그램의 어느 부분이 각 변수에 접근해야 하는지도 고려해야 합니다; 그에 따라 전역 또는 지역 변수를 채택하세요. Go 프로그램에서는 지역 변수가 일반적으로 더 흔합니다.
상수
상수는 변수와 비슷하지만, 선언된 후에는 수정할 수 없습니다. 상수는 프로그램에서 여러 번 사용되지만 변경되지 않아야 하는 값을 정의할 때 유용합니다.
예를 들어, 쇼핑카트 시스템에서 세율을 선언하고 싶다면, 상수를 사용하고 프로그램의 여러 부분에서 세금을 계산할 수 있습니다. 미래의 어느 시점에서 세율이 변경되면, 프로그램에서 단 하나의 위치에서 값을 변경하면 됩니다. 변수를 사용했다면, 프로그램의 어딘가에서 실수로 값이 변경될 수 있으며, 이는 잘못된 계산으로 이어질 수 있습니다.
상수를 선언하려면, 다음과 같은 문법을 사용할 수 있습니다:
OutputSammy
선언된 후에 상수를 수정하려고 시도하면, 컴파일 시간 에러를 받게 됩니다:
Outputcannot assign to shark
상수는 untyped
일 수 있습니다. 이는 정수형 데이터와 같은 숫자를 다룰 때 유용할 수 있습니다. 상수가 untyped
라면, 명시적으로 변환되지만, typed
상수는 그렇지 않습니다. 상수를 어떻게 사용할 수 있는지 살펴보겠습니다:
Output8760
21900
21960
종류를 선언할 때 상수에 타입을 지정하면, 정확히 그 타입이 됩니다. 여기서 leapYear
라는 상수를 선언할 때, 데이터 타입 int32
으로 정의합니다. 따라서 이는 typed
상수로, 오로지 int32
데이터 타입으로만 작동할 수 있습니다. year
라는 상수는 타입을 주지 않으므로, untyped
로 간주됩니다. 이렇게 하면, 모든 정수 데이터 타입으로 사용할 수 있습니다.
hours
가 정의될 때, 타입을 명시적으로 주지 않았기 때문에 int
타입으로 추론되었습니다, hours := 24
. minutes
를 선언할 때는 명시적으로 int32
로 선언했습니다, minutes := int32(60)
.
이제 각 계산을 하나씩 거쳐보고, 왜 그런지 이해해봅시다:
이 경우, hours
는 int
타입이고, years
는 타입이 지정되지 않음입니다. 프로그램이 컴파일될 때, years
를 int
타입으로 명시적으로 변환하여 곱셈 연산이 성공할 수 있게 합니다.
이 경우, minutes
는 int32
타입이고, year
는 타입이 지정되지 않음입니다. 프로그램이 컴파일될 때, years
를 int32
타입으로 명시적으로 변환하여 곱셈 연산이 성공할 수 있게 합니다.
이 경우, minutes
는 int32
타입이고, leapYear
는 타입이 지정된 int32
상수입니다. 이번에는 두 변수가 이미 같은 타입이므로 컴파일러가 할 일이 없습니다.
타입이 지정된 두 타입을 곱하려고 하는데 호환되지 않는다면, 프로그램은 컴파일되지 않습니다:
Outputinvalid operation: hours * leapYear (mismatched types int and int32)
이 경우, hours
는 int
타입으로 추론되었고, leapYear
는 int32
타입으로 명시적으로 선언되었습니다. Go는 타입이 지정된 언어이므로, int
와 int32
는 수학적 연산에 호환되지 않습니다. 이들을 곱하려면 int32
또는 int
타입으로 변환해야 합니다.
결론
이 튜토리얼에서는 Go 내에서 변수의 몇 가지 일반적인 사용 사례를 살펴보았습니다. 변수는 프로그래밍의 중요한 구성 요소로서, 프로그램에서 사용하는 데이터 타입의 값을 대표하는 기호 역할을 합니다.
Source:
https://www.digitalocean.com/community/tutorials/how-to-use-variables-and-constants-in-go