조합형

Union type

컴퓨터 과학에서 유니언(union)은 메모리에서 동일한 위치 내에 여러 가지 표현이나 형식 중 하나를 가질 수 있는 입니다. 이러한 데이터 구조를 유지할 수 있는 변수로 구성됩니다.일부 프로그래밍 언어는 그러한 값과 변수를 설명하기 위해 조합 유형이라고 하는 특수 데이터 유형을 지원합니다.다시 말해, 유니언 타입 정의는 허용된 수많은 프리미티브 타입들 중 어떤 타입이 그 인스턴스에 저장될 수 있는지를 지정할 것입니다. 예를 들어, "float or long integer.부동소수점과 정수를 모두 포함하도록 정의될 수 있는 레코드(또는 구조)와 대조적으로, 조합에서는 임의의 주어진 시간에 하나의 값만 있습니다.

조합은 다양한 데이터 유형의 변수를 저장하는 데 사용되는 메모리 덩어리로 나타낼 수 있습니다.필드에 새 값이 할당되면 기존 데이터를 새 데이터로 덮어씁니다.값을 저장하는 메모리 영역에는 고유한 유형(바이트 또는 메모리 단어만 제외)이 없지만, 값은 메모리 영역에 마지막으로 기록된 값의 유형을 가지는 여러 추상 데이터 유형 중 하나로 취급될 수 있습니다.

유형 이론에서, 합집합은 합집합을 갖는데, 이것은 수학에서 분리결합에 해당합니다.

언어와 유형에 따라 균등화를 위한 할당, 비교 등 일부 작업에서 특정 유형을 알지 못한 채 조합 값이 사용될 수 있습니다.일부 외부 정보를 사용하거나 태그가 지정된 결합을 사용하여 다른 작업에 이러한 지식이 필요할 수 있습니다.

태그없는 조합

태그 없는 결합은 사용의 한계 때문에 일반적으로 (C와 같이) 유형화되지 않은 언어 또는 유형화되지 않은 결합은 일반적으로 (C와 같이) 유형화되지 않은 방식으로만 제공됩니다.데이터 유형 태그를 저장하는 데 공간이 필요 없는 단순 태그 결합에 비해 장점이 있습니다.

"연합"이라는 이름은 유형의 공식적인 정의에서 비롯되었습니다.유형이 해당 유형이 취할 수 있는 모든 값의 집합으로 간주될 경우, 결합 유형은 단순히 해당 필드가 취할 수 있는 모든 값을 취할 수 있으므로 구성 유형의 수학적 결합입니다.또한 수학조합은 중복을 버리기 때문에 조합의 하나 이상의 분야가 하나의 공통된 가치를 가질 수 있다면 가치만으로는 어떤 분야가 마지막으로 작성되었는지 알 수 없습니다.

그러나 조합의 유용한 프로그래밍 기능 중 하나는 더 작은 데이터 요소를 더 큰 데이터 요소에 매핑하여 조작을 쉽게 하는 것입니다.예를 들어, 4바이트와 32비트 정수로 구성된 데이터 구조는 부호가 없는 64비트 정수와 결합을 형성할 수 있으므로 비교 등의 목적으로 보다 쉽게 접근할 수 있습니다.

다양한 프로그래밍 언어의 조합

알골68

ALGOL 68에는 태그된 유니언이 있으며, 실행 시 case 절을 사용하여 구성 유형을 구별하고 추출합니다.다른 조합을 포함하는 조합은 모든 구성 가능성의 집합으로 취급되며, 상황에 따라 필요한 경우 조합은 자동적으로 더 넓은 조합으로 강제됩니다.조합에는 명시적으로 값이 포함되지 않을 수 있으며, 이 값은 런타임에 구별될 수 있습니다.예를 들면 다음과 같습니다.

모드 노드 = union(real, int, string, void); 노드 n : = "float"; case n in (real r): print(("real:", r)), (inti): print(("int:", i), (strings): print("string:", s), (pring): print("float:", "EMPTY"), out print(("float:","n") esac

C/C++ 조합형의 구문과 캐스트의 개념은 ALGOL 68로부터 도출되었지만 태그가 없는 [1]형태였습니다.

C/C++

C와 C++에서 태그 없는 결합은 각 데이터 구성원이 메모리의 동일한 위치에서 시작한다는 점을 제외하고는 구조(구조)와 거의 동일하게 표현됩니다.데이터 구성원은 구조에서와 마찬가지로 원시 값일 필요는 없으며, 실제로 구조 또는 다른 결합일 수도 있습니다.C++(C++11 이후)는 또한 데이터 멤버가 완전한 생성자/파괴자 및/또는 복사 생성자 또는 중요하지 않은 복사 할당 연산자를 갖는 모든 유형이 되도록 허용합니다.예를 들어, 표준 C++ 문자열을 조합원으로 가질 수 있습니다.

유니언의 주된 용도는 하드웨어 입출력 액세스, 비트필드 및 워드 공유, 또는 유형 펀닝과 같은 다양한 데이터 유형을 통해 공통 위치에 액세스할 수 있도록 하는 것입니다.조합은 낮은 수준의 다형성을 제공할 수도 있습니다.그러나 유형 검사는 없으므로 적합한 필드가 다른 컨텍스트에서 액세스되도록 하는 것은 프로그래머에게 달려 있습니다.조합 변수의 관련 필드는 일반적으로 다른 변수의 상태에 따라 결정되며, 경우에 따라 엔클로저 구조로 결정될 수도 있습니다.

하나의 일반적인 C 프로그래밍 관용구는 조합을 사용하여 조합의 한 필드에 할당하고 값의 원시 표현에 의존하는 코드에서 수행되는 것처럼 C++가 재해석 캐스트라고 부르는 것을 수행합니다.실질적인 예로는 IEEE 표현을 사용한 제곱근 계산 방법이 있습니다.그러나 이것은 일반적으로 노조의 안전한 사용이 아닙니다.

구조 및 조합 지정자의 양식이 동일합니다.[...] 조합원 중 가장 많은 조합원이 가입할 수 있는 규모입니다.언제든지 조합 개체에 구성원 중 하나 이상의 값을 저장할 수 있습니다.적절히 변환된 유니언 객체에 대한 포인터는 각 유니언 객체(또는 멤버가 비트 필드인 경우 해당 유니언이 위치한 단위)를 가리키며, 그 반대의 경우도 마찬가지입니다.

ANSI/ISO 9899:1990 (the ANSI C standard) Section 6.5.2.1

익명조합

C++, C11, 그리고 많은 컴파일러들의 비표준 확장자로서, 유니언들은 익명일 수도 있습니다.데이터 구성원은 참조할 필요가 없고 직접 액세스됩니다.C11에서는 다른 구조나 [2]조합의 구성원이어야 하며, C++에서는 메서드나 액세스 지정자를 가질 수 없습니다.

구문에서 클래스 이름 부분을 단순히 생략한다고 해서 유니언이 익명 유니언이 되는 것은 아닙니다.조합이 익명조합의 자격을 갖추기 위해서는 선언문이 객체를 선언해서는 안 됩니다.예:

#허튼소리 <아이오스트림> #허튼소리 <cstdint>  인트 주된() {    연합의 {       흘러가다 f;       std::unint32_t d; // 플로트 폭이 32비트라고 가정합니다.    };     f = 3.14f;    std::꾸트린 << "3.14f의 16진수 표현:"               << std::육각형의 << d << '\n'; } 

익명조합은 C에서도 유용합니다.struct네임스페이스의 [3]느낌을 제공하는 정의.

투명조합

GCC, Clang, IBM XLC for AIX와 같은 컴파일러에서 a.transparent_union조합 유형에 대해 속성을 사용할 수 있습니다.조합에 포함된 유형은 모든 유형의 크기가 동일한 경우 함수 호출에서 조합 유형 자체로 투명하게 변환할 수 있습니다.주로 초기 유닉스 확장과 나중에 재표준화를 통해 [4]필요한 여러 매개변수 인터페이스를 사용하는 기능을 목적으로 합니다.

코볼

코볼에서 조합 데이터 항목은 두 가지 방식으로 정의됩니다.첫번째는.RENAMES (66 level) 키워드로, 이전 데이터 항목과 동일한 메모리 위치 위에 두 번째 영숫자 데이터 항목을 효과적으로 매핑합니다.아래 예제 코드에서 데이터 항목 PERSONA-REC은 다른 그룹과 숫자 데이터 항목을 포함하는 그룹으로 정의됩니다.PERSONA-DATA는 PERSONA-REC의 이름을 변경하는 영숫자 데이터 항목으로 정의되며, 해당 항목 내에서 계속되는 데이터 바이트를 문자 데이터로 처리합니다.

  01  사용자-REC.       05  사용자-이름.           10  사용자-이름-마지막    PIC X(12).           10  사용자-이름-첫번째   PIC X(16).           10  사용자-이름-MID     PIC X.       05  사용자-ID               PIC 9(9) 포장됨-십진법.      01  사용자-DATA                 이름 바꾸기 사용자-REC. 

조합 유형을 정의하는 두 번째 방법은 REFREEDINES 키워드를 사용하는 것입니다.아래 예제 코드에서 데이터 항목 VERS-NUM은 버전 번호를 포함하는 2바이트 이진 정수로 정의됩니다.두 번째 데이터 항목 VERS-BYTES는 두 문자 영숫자 변수로 정의됩니다.두 번째 항목이 첫 번째 항목에 대해 재정의되었기 때문에 두 항목은 메모리에서 동일한 주소를 공유하므로 동일한 기본 데이터 바이트를 공유합니다.첫 번째 항목은 두 개의 데이터 바이트를 이진 값으로 해석하고, 두 번째 항목은 바이트를 문자 값으로 해석합니다.

  01  VERS-INFO.       05  VERS-NUM        PICS9(4) COMP.       05  VERS-BYTES      PIC X(2)                           재정의 VERS-NUM 

파스칼

파스칼에는 조합을 만드는 두 가지 방법이 있습니다.하나는 변종 기록을 통과하는 일반적인 방법입니다.두 번째는 변수를 절대로 선언하는 비표준 수단으로, 다른 변수와 동일한 메모리 위치 또는 절대 주소에 배치됨을 의미합니다.모든 파스칼 컴파일러는 변종 레코드를 지원하지만 일부는 절대 변수를 지원합니다.

이 예제에서는 바이트는 8비트, 단어는 16비트, 정수는 32비트로 구성되어 있습니다.

다음 예제에서는 비표준 절대 형식을 보여 줍니다.

변태의     A: 정수;     B: 배열하다[1..4]  바이트 절대의 A;     C: 정수 절대의 0; 

첫 번째 예에서 배열 B의 각 요소는 변수 A의 특정 바이트 중 하나에 매핑됩니다.두 번째 예제에서 변수 C는 정확한 기계 주소 0에 할당됩니다.

다음 예제에서는 레코드에 변형이 있으며 일부는 다른 레코드와 동일한 위치를 공유합니다.

유형      모양. = (원형, 광장, 삼각형);      치수 = 기록.         사례. 피규어: 모양.              원형: (지름: 진짜);            광장: (: 진짜);            삼각형: (: 진짜; 각도1, 각도2: 0..360)         끝.; 

PL/I

PL/I에서 유니언의 원래 용어는 셀([5]cell)이었는데, 지금도 몇몇 컴파일러들에 의해 유니언의 동의어로 받아들여지고 있습니다.조합 선언은 조합 선언 내의 동일한 수준의 요소가 동일한 저장소를 차지하는 구조 정의와 유사합니다.조합의 요소는 구조 및 [6]: pp192–193 배열을 포함한 모든 데이터 유형이 될 수 있습니다.여기서 vers_num 및 vers_bytes는 동일한 저장 위치를 차지합니다.

  1  vers_info         연합의,      5 vers_num        고정된. 이진법의,      5 vers_limit      사진 '(2)A'; 

통합 선언의 대안은 저장 선언의 대안이 되는 DEFINED 속성이지만, 기본 및 정의된 변수의 데이터 유형이 [6]: pp.289–293 일치해야 합니다.

녹은 태그가 달린 결합과 태그가 없는 결합을 모두 구현합니다.Rust에서는 태그가 지정된 유니언이 다음을 사용하여 구현됩니다.enum키워드.대부분의 다른 언어에서 열거된 유형과 달리 Rust의 열거형 변형은 튜플이나 구조의 형태로 추가 데이터를 포함할 수 있으므로 단순한 [7]열거형이 아닌 태그가 지정된 결합으로 만듭니다.

녹은 또한 태그 없는 조합을 지원합니다.union키워드.러스트의 유니언들의 메모리 레이아웃은 [8]기본적으로 정의되지 않지만, 유니언들은#[repr(C)]속성은 [9]C의 동등한 결합과 똑같이 메모리에 배치됩니다.연합의 분야를 읽는 것은 오직 하나의 안에서만 이루어질 수 있습니다.unsafe함수 또는 블록입니다. 컴파일러가 유니언의 데이터가 필드 유형에 유효한지 보장할 수 없기 때문입니다. 그렇지 않으면 정의되지 않은 [10]동작이 발생합니다.

구문 및 예제

C/C++

C와 C++에서 구문은 다음과 같습니다.

연합의 <이름.> {     <자료형>  <1세인트 변수 이름.>;     <자료형>  <2nd 변수 이름.>;     .     .     .     <자료형>  <n번째 변수 이름.>; } <연합의 변수 이름.>; 

다음 예제에서 볼 수 있듯이 구조물은 조합의 멤버가 될 수도 있습니다.

연합의 name1 {     짜임새 있는 name2     {           인트     a;         흘러가다   b;         차를    c;     } 스바;     인트     d; } 유바; 

이 예제는 변수를 정의합니다.uvar연합체로서(라고 부름)name1), 2개의 멤버를 포함하고 있습니다.name2)의 이름을 붙였습니다svar(즉, 3개의 멤버를 포함함) 및 다음과 같은 정수 변수를 포함합니다.d.

구조 및 배열 내에서 결합이 발생할 수 있으며, 그 반대의 경우도 있습니다.

짜임새 있는 {       인트 깃발들;     차를 *이름.;     인트 u타입의;     연합의 {         인트 아이벌의;         흘러가다 fval의;         차를 *스발의;     } u; } 심탭[NSYM]; 

숫자는 다음과 같이 지칭됩니다.symtab[i].u.ival그리고 문자열 sval의 첫번째 문자는 다음 중 하나에 의해 작성됩니다.*symtab[i].u.sval아니면symtab[i].u.sval[0].

PHP

유니언 타입은 PHP 8.[11]0에 도입되었습니다.값은 언어별로 형식과 함께 암묵적으로 "태그"되어 있으며, "gettype()"으로 검색할 수 있습니다.

학급  {     사적인 인트 흘러가다 $foo;      일반의 기능. 정사각형 및 추가(흘러가다 인트 달러바): 인트 흘러가다     {         돌아가다 달러바 ** 2 + $ this->푸우;     } } 

파이썬

타이핑 지원은 파이썬 3.[12]5에 도입되었습니다.조합 유형에 대한 새로운 구문은 파이썬 3.[13]10에 도입되었습니다.

학급 :     푸우 = 0      데프 정사각형_그리고_추가(자신, : 인트   흘러가다) -> 인트   흘러가다:         돌아가다  ** 2 + 자신.푸우 

타이프스크립트

조합 유형은 [14]TypeScript에서 지원됩니다.값은 언어별로 형식과 함께 암묵적으로 "태그"되어 있으며 "type of()"로 검색할 수 있습니다.

기능. 후계자(n: 번호   비긴트): 번호   비긴트 {     돌아가다 ++n } 

Rust에서 태그가 지정된 조합은enum키워드이며, 튜플 및 구조 변형을 포함할 수 있습니다.

열거형 {Bar(i32), Baz { x: 문자열, y: i32}, }

러스트의 태그 없는 조합은union키워드:

union Foo { bar: i32, baz: boole, }

태그가 지정되지 않은 조합의 필드에서 읽게 되면 조합의 데이터가 필드의 유형으로 유효하지 않으므로 정의되지 않은 동작이 발생합니다.unsafe블록:

x = Foo {bar: 10}, y = security {x.bar }, // y가 10으로 설정되며, 정의되지 않은 동작이 발생하지 않습니다.z = 안전하지 않은 { x.baz}; // x에 저장된 값이 유효한 boole이 아니기 때문에 정의되지 않은 동작이 발생합니다.

참고 항목

참고문헌

  1. ^ Ritchie, Dennis M. (March 1993). "The Development of the C Language". ACM SIGPLAN Notices. 28 (3): 201–208. doi:10.1145/155360.155580. The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol's adherents would approve of. The central notion I captured from Algol was a type structure based on atomic types (including structures), composed into arrays, pointers (references), and functions (procedures). Algol 68's concept of unions and casts also had an influence that appeared later.
  2. ^ "6.63 Unnamed Structure and Union Fields". Retrieved 2016-12-29.
  3. ^ Siebenmann., Chris. "CUnionsForNamespaces". utcc.utoronto.ca.
  4. ^ "Common Type Attributes: transparent_union". Using the GNU Compiler Collection (GCC).
  5. ^ IBM Corporation (March 1968). IBM System/360 PL/I Language Specifications (PDF). p. 52. Retrieved Jan 22, 2018.
  6. ^ a b IBM Corporation (Dec 2017). Enterprise PL/I for z/OS PL/I for AIX IBM Developer for z Systems PL/I for windows Language Reference (PDF). Retrieved Jan 22, 2018.
  7. ^ "How Rust Implements Tagged Unions - Pat Shaughnessy". patshaughnessy.net. Retrieved 2023-04-25.
  8. ^ "Union types - The Rust Reference". doc.rust-lang.org. Retrieved 2023-04-25.
  9. ^ "Type layout - The Rust Reference". doc.rust-lang.org. Retrieved 2023-04-25.
  10. ^ "Unions - The Rust Reference". doc.rust-lang.org. Retrieved 2023-04-25.
  11. ^ Karunaratne, Ayesh. "PHP 8.0: Union Types". PHP.Watch. Retrieved 30 November 2020.
  12. ^ "typing — Support for type hints — Python 3.9.7 documentation". docs.python.org. Retrieved 8 September 2021.
  13. ^ "PEP 604 -- Allow writing union types as X Y". Python.org. Retrieved 8 September 2021.
  14. ^ "Handbook - Unions and Intersection Types". www.typescriptlang.org. Retrieved 30 November 2020.

외부 링크