C 구조체 선언
C 구조체 선언 (struct)
lib 안에서 struct를 선언하면 C 구조체를 선언하는 셈입니다:
lib C
# In C:
#
# struct TimeZone {
# int minutes_west;
# int dst_time;
# };
struct TimeZone
minutes_west : Int32
dst_time : Int32
end
end
같은 타입의 필드를 여러 개 묶어서 지정할 수도 있어요:
lib C
struct TimeZone
minutes_west, dst_time : Int32
end
end
재귀 구조체도 예상한 그대로 동작합니다:
lib C
struct LinkedListNode
prev, _next : LinkedListNode*
end
struct LinkedList
head : LinkedListNode*
end
end
lib 안에 정의된 구조체는 모듈처럼 다른 lib 구조체 내부에 include 할 수 있어요. 예를 들면:
lib Lib
struct Foo
x : Int32
y : Int16
end
struct Bar
include Foo
z : Int8
end
end
Lib::Bar.new # => Lib::Bar(@x=0, @y=0, @z=0)
구조체의 인스턴스를 만들려면 new를 씁니다:
tz = C::TimeZone.new
이러면 구조체가 스택(stack)에 할당돼요.
C 구조체는 모든 필드가 "0"으로 초기화된 상태로 시작합니다. 정수와 부동소수점은 0에서, 포인터는 주소 0에서 시작하는 식이죠.
이런 초기화를 피하고 싶다면 uninitialized를 쓸 수 있어요:
tz = uninitialized C::TimeZone
tz.minutes_west # => some garbage value
프로퍼티를 설정하고 읽을 수도 있습니다:
tz = C::TimeZone.new
tz.minutes_west = 1
tz.minutes_west # => 1
할당하는 값이 프로퍼티의 타입과 정확히 같지 않다면, to_unsafe가 시도됩니다.
명명 인자(named arguments)와 비슷한 문법으로 일부 필드를 초기화할 수도 있어요:
tz = C::TimeZone.new minutes_west: 1, dst_time: 2
tz.minutes_west # => 1
tz.dst_time # => 2
C 구조체는 함수나 메서드에 값(복사본)으로 전달되고, 메서드에서 반환될 때도 값으로 반환됩니다:
def change_it(tz)
tz.minutes_west = 1
end
tz = C::TimeZone.new
change_it tz
tz.minutes_west # => 0
구조체 필드 타입에 쓰이는 표기는 타입 문법(type grammar)을 참고하세요.
출처: Crystal 공식 문서