1543 words
8 minutes
[Mojo] Variables
Mojo의 변수 선언과 사용
mojo setupGo to MojoSetup
1. 변수의 종류
Mojo에서는 모든 변수가 가변적(mutable)이며, 두 가지 방식으로 변수를 선언할 수 있습니다
1.1 명시적 변수 선언 (Explicitly-declared variables)
var
키워드를 사용하여 변수를 선언합니다. 타입 어노테이션을 포함할 수 있습니다
var a = 5
var b: Float64 = 3.14
- 초기화 없이 선언 가능:
var value: Float64
- 렉시컬 스코핑(lexical scoping) 따름
- 타입 어노테이션 사용 가능
1.2 암시적 변수 선언 (Implicitly-declared variables)
할당 문장으로 직접 변수를 생성합니다
a = 5
b = 3.14
- 함수 레벨 스코핑
- 첫 할당값의 타입으로 변수 타입이 결정됨
2. 타입 시스템
2.1 강타입 시스템 (Strong typing)
지식모든 변수는 강타입입니다
- 생성 시 타입이 결정되며 변경 불가
- 다른 타입의 값 할당 시 에러 발생
count = 1 # count는 Int 타입
count = "One" # 에러: StringLiteral을 Int로 변환 불가
2.2 암시적 타입 변환 (Implicit conversion)
지식일부 타입은 다른 타입으로부터의 암시적 변환을 지원
var test: Float64 = 50 # Int에서 Float64로 자동 변환
print(test) # 출력: 50.0
3. 스코프 규칙
3.1 var 키워드 사용 시 (렉시컬 스코프)
def lexical_scopes():
var num = 1
if num == 1:
var num = 2 # 새로운 변수 생성 (shadowing)
print(num) # 2 출력
print(num) # 1 출력 (외부 스코프 변수)
3.2 암시적 선언 시 (함수 레벨 스코프)
def function_scopes():
num = 1
if num == 1:
num = 2 # 함수 레벨 변수 수정
print(num) # 2 출력
print(num) # 2 출력
4. 타입 어노테이션 (Type Annotations)
4.1 기본 사용법
타입 어노테이션을 사용하면 변수의 타입을 명시적으로 지정할 수 있습니다
var name: String = get_name()
- var 키워드와 함께 사용해야 함
- 코드의 가독성과 의도를 명확히 전달
- 함수 반환값의 타입을 모르더라도 변수 타입을 명시 가능
4.2 단일 인자 생성자를 가진 타입의 초기화
지식단일 인자 생성자를 가진 타입은 두 가지 방식으로 초기화 가능
var name1: String = "Sam" # 타입 어노테이션 사용
var name2 = String("Sam") # 직접 생성자 호출
5. 지연 초기화 (Late Initialization)
지식타입 어노테이션을 사용하면 변수를 나중에 초기화 가능
fn my_function(x: Int):
var z: Float32 # 타입만 선언
if x != 0:
z = 1.0 # 조건에 따라 초기화
else:
z = foo()
print(z)
- 초기화되지 않은 변수 사용 시 컴파일 에러 발생
- 타입 선언이 반드시 필요
- 값 할당 전 사용 불가
6. 암시적 타입 변환의 조건
암시적 타입 변환이 가능 조건:
- 대상 타입이 @implicit 데코레이터로 표시된 생성자를 가짐
- 해당 생성자가 변환하려는 값과 일치하는 단일 필수 인자를 받음
var number: Float64 = Int(1) # Int를 Float64로 암시적 변환
print(number) # 출력: 1.0
==> 아래와 같이 표현할 수 있어요
var number = Float64(1) # 직접 생성자 호출
함수 호출할 때도 암시적 변환이 적용됩니다
fn take_float(value: Float64):
print(value)
fn pass_integer():
var value: Int = 1
take_float(value) # Int가 Float64로 자동 변환
조심조심일반적으로 암시적 변환은 데이터 손실이 없는 경우에만 지원합니다
Function Scope in Mojo
함수 레벨 스코프 vs 렉시컬 스코프
Mojo에서는 변수 선언 방식에 따라 두 가지 다른 스코프 규칙이 적용됩니다
1. 암시적 선언의 함수 레벨 스코프
암시적으로 선언된 변수(var 키워드 없이 선언)는 Python과 같은 함수 레벨 스코프를 따릅니다
def demonstrate_function_scope():
count = 0 # 함수 레벨에서 변수 선언
if True:
count = 5 # 같은 변수를 수정
temp = 10 # 새로운 변수 선언
print(count) # 출력: 5
print(count) # 출력: 5 (if 블록의 변경사항이 유지됨)
print(temp) # temp도 접근 가능 (함수 전체가 스코프)
- 변수는 함수 전체에서 동일한 스코프를 공유
- 내부 블록에서 수정된 값은 함수 전체에 영향
- 새로 선언된 변수도 함수 전체에서 접근 가능
- Python 스타일의 변수 스코핑과 동일
2. var 키워드의 렉시컬 스코프
반면, var로 선언된 변수는 렉시컬 스코프를 따릅니다
def demonstrate_lexical_scope():
var count = 0 # 외부 스코프 변수
var outer = 1
if True:
var count = 5 # 새로운 변수 생성 (shadowing)
var inner = 2 # 내부 스코프 변수
print(count) # 출력: 5
print(outer) # 외부 변수 접근 가능
print(count) # 출력: 0 (외부 변수는 변경되지 않음)
# print(inner) # 에러! inner는 if 블록 밖에서 접근 불가
- 각 블록이 고유한 스코프를 생성
- 내부 스코프에서 외부 변수 접근 가능
- 같은 이름의 변수 선언 시 shadowing 발생
- 내부 스코프의 변수는 해당 블록 밖에서 접근 불가
3. 두 스코프 규칙의 실제 응용
두 스코프 규칙을 혼합해서 사용할 때
def mixed_scope_example():
var x = 0 # 렉시컬 스코프 변수
y = 0 # 함수 스코프 변수
if True:
var x = 1 # 새로운 x 생성 (shadowing)
y = 1 # 기존 y 수정
var z = 2 # 렉시컬 스코프의 새 변수
w = 3 # 함수 스코프의 새 변수
print(x) # 출력: 0 (원래 x 유지)
print(y) # 출력: 1 (수정된 y)
# print(z) # 에러! z는 if 블록 스코프
print(w) # 출력: 3 (함수 스코프라 접근 가능)
- 함수 레벨 스코프는 Python 개발자들에게 친숙한 동작을 제공
- 렉시컬 스코프는 더 엄격한 변수 관리와 안전성을 제공
- 두 스코프 규칙을 상황에 맞게 적절히 선택하여 사용 가능
Reference
[Mojo] Variables
https://compy07.github.io/Blog/posts/mojo/tutorial/variable/