클래스 변수
클래스 변수 (Class variables)
클래스 변수는 인스턴스가 아니라 클래스에 묶여 있어요. at 기호가 두 개(@@) 붙는 게 특징입니다. 예시를 볼게요:
class Counter
@@instances = 0
def initialize
@@instances += 1
end
def self.instances
@@instances
end
end
Counter.instances # => 0
Counter.new
Counter.new
Counter.new
Counter.instances # => 3
클래스 변수는 클래스 메서드나 인스턴스 메서드 양쪽에서 읽고 쓸 수 있어요.
기본값과 함께 초기화되면, 타입 추론 알고리즘이 변수의 타입을 대부분 암묵적으로 알아낼 수 있습니다:
module InferredTypes
@@integer = 1 # : Int32
@@string = "" # : String
end
다만 메서드 호출이 들어간 복잡한 표현식 같은 경우는 타입을 추론하지 못해요. 그런 경우엔 변수 타입을 명시적으로 지정해 주어야 합니다:
def generate_foo
1
end
module NonInferableType
@@untyped = generate_foo() # Error: can't infer the type of class variable '@@foo' of NonInferableTypes
@@typed : Int32 = generate_foo()
end
클래스 변수는 서브클래스에 상속되는데, 의미상 타입은 같지만 각 클래스마다 런타임 값이 다릅니다. 예시로 볼게요:
class Parent
@@numbers = [] of Int32
def self.numbers
@@numbers
end
end
class Child < Parent
end
Parent.numbers # => []
Child.numbers # => []
Parent.numbers << 1
Parent.numbers # => [1]
Child.numbers # => []
클래스 변수는 모듈과 구조체에도 연결할 수 있어요. 위와 마찬가지로 타입을 include하거나 상속하는 타입들에게 상속됩니다.
출처: Crystal 공식 문서
더 알아보기 (Learn more)
- 인스턴스 변수 —
@하나로 시작하는 인스턴스 변수 - 타입 추론 — 변수 타입이 결정되는 방식
- 상수 (Constants) — 이름 붙은 상숫값