내장 어노테이션
내장 어노테이션 (Built-in annotations)
Crystal 언어에는 미리 정의되어 있는 어노테이션들이 몇 가지 있어요. 컴파일러가 이 어노테이션들을 코드 생성이나 deprecation 경고 같은 용도로 사용해요. 여기에 더해, Crystal 표준 라이브러리도 추가 어노테이션을 정의하고 있어요.
출처: Crystal 공식 문서
본문
Link
컴파일러에게 C 라이브러리를 어떻게 링크할지 알려줘요. 자세한 내용은 lib 섹션에서 다뤄요.
참고: 더 자세한 내용은
LinkAPI 문서를 확인해 보세요.
Extern
이 어노테이션을 Crystal struct에 붙이면, 그 struct를 lib 선언에서 사용할 수 있어요:
@[Extern]
struct MyStruct
end
lib MyLib
fun my_func(s : MyStruct) # OK (gives an error without the Extern annotation)
end
struct가 C의 union처럼 동작하게 만들 수도 있어요. 다만 이건 꽤 안전하지 않을 수 있다는 점은 기억해 두세요:
# A struct to easily convert between Int32 codepoints and Chars
@[Extern(union: true)]
struct Int32OrChar
property int = 0
property char = '\0'
end
s = Int32OrChar.new
s.char = 'A'
s.int # => 65
s.int = 66
s.char # => 'B'
ThreadLocal
@[ThreadLocal] 어노테이션은 클래스 변수와 C 외부 변수에 붙일 수 있어요. 그 변수들을 스레드 로컬(thread local)로 만들어주죠.
class DontUseThis
# One for each thread
@[ThreadLocal]
@@values = [] of Int32
end
ThreadLocal은 표준 라이브러리에서 런타임을 구현할 때 쓰여요. 그래서 표준 라이브러리 바깥에서는 굳이 필요하거나 쓰일 일이 없어요.
Packed
C struct를 packed로 표시해서, 필드 사이에 패딩 바이트가 자동으로 삽입되는 걸 막아줘요. 이건 보통 C 라이브러리가 명시적으로 packed struct를 사용할 때만 필요해요.
AlwaysInline
컴파일러에게 메서드를 항상 인라인하라는 힌트를 줘요:
@[AlwaysInline]
def foo
1
end
NoInline
컴파일러에게 메서드 호출을 절대 인라인하지 말라고 알려줘요. 메서드가 yield 한다면 함수는 항상 인라인되기 때문에 이 어노테이션은 효과가 없어요.
@[NoInline]
def foo
1
end
ReturnsTwice
메서드나 lib fun을 두 번 반환(return)하는 것으로 표시해요. C의 setjmp가 이런 함수의 예시예요.
Raises
메서드나 lib fun이 예외를 던질 수 있다고 표시해요. 이 내용은 callbacks 섹션에서 다뤄요.
CallConvention
lib fun의 호출 규약(call convention)을 나타내요. 예를 들어:
lib LibFoo
@[CallConvention("X86_StdCall")]
fun foo : Int32
end
유효한 호출 규약 목록은 다음과 같아요:
- C (기본값)
- Fast
- Cold
- WebKit_JS
- AnyReg
- X86_StdCall
- X86_FastCall
참고: 더 자세한 내용은 LLVM 문서를 확인해 보세요.
Flags
enum을 "flags enum"으로 표시해요. 이렇게 하면 to_s 같은 일부 메서드의 동작이 달라져요.
참고: 더 자세한 내용은
FlagsAPI 문서를 확인해 보세요.
Deprecated
어떤 기능(예: 메서드, 타입, 파라미터)을 deprecated로 표시해요.
Deprecation은 API 문서에 표시되고, deprecated 기능을 사용하면 컴파일러가 경고를 출력해요.
참고: 더 자세한 내용은
DeprecatedAPI 문서를 확인해 보세요.
TargetFeature
def나 fun 범위로 특정 CPU 기능이나 CPU 모델을 활성화할 수 있게 해줘요. 그래서 SIMD 명령 같은 서로 다른 기능에 최적화된 함수들을 하나의 실행 파일에 담아 컴파일할 수 있어요. 예를 들어:
{% if flag?(:x86_64) %}
@[TargetFeature("+avx2")]
def foo_avx2
end
{% end %}
참고: 더 자세한 내용은
TargetFeatureAPI 문서를 확인해 보세요.
더 알아보기
@[Link]는 C 라이브러리 링크를,@[Extern]은 struct를 C 세계에서 쓸 수 있게 하는 데 쓰여요.AlwaysInline/NoInline은 인라인 힌트,Raises/ReturnsTwice는 호출 동작을,CallConvention은 호출 규약을 다뤄요.- Flags 열거형에서는
Flags어노테이션을, deprecated는Deprecated로 표시해요.