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/
