Changeset 1d5e5601 for doc/theses/jiada_liang_MMath
- Timestamp:
- Mar 1, 2024, 11:14:23 AM (10 months ago)
- Branches:
- master
- Children:
- 647e2ea
- Parents:
- 924534e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/relatedwork.tex
r924534e r1d5e5601 2 2 \label{s:RelatedWork} 3 3 4 An enumeration type exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, \CC, Go~\cite{Go}, Java~\cite{Java}, Modula-3~\cite{Modula-3}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}, and the algebraic data-typein functional programming.4 Enumeration types exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, \CC, Go~\cite{Go}, Java~\cite{Java}, Modula-3~\cite{Modula-3}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}, and algebraic data-types in functional programming. 5 5 Among theses languages, there are a large set of overlapping features, but each language has its own unique extensions and restrictions. 6 6 … … 14 14 PI = 3.14159; Plus = '+'; Fred = 'Fred'; 15 15 \end{pascal} 16 The enumerator type is inferred from the constant-expression type. 17 There is no notion of an ordered set, modulo the \lstinline[language=pascal]{set of} type. 16 Here, there is no enumeration because there is no specific type (pseudo enumeration). 17 Hence, there is no notion of a (possibly ordered) set, modulo the \lstinline[language=pascal]{set of} type. 18 The type of each constant name (enumerator) is inferred from the constant-expression type. 18 19 19 20 Free Pascal~\cite[\S~3.1.1]{FreePascal} is a modern, object-oriented version of classic Pascal, with a C-style enumeration type. … … 38 39 An Ada enumeration type is an ordered list of constants, called \Newterm{literals} (enumerators). 39 40 \begin{ada} 40 type RGB is ( @Red@, @Green@, Blue ); -- 3 literals (enumerators)41 \end{ada} 42 No other enumerators are assignable to objects of this type.41 type RGB is ( Red, Green, Blue ); -- 3 literals (enumerators) 42 \end{ada} 43 Object initialization and assignment are restricted to the enumerators of this type. 43 44 Enumerators without an explicitly designated constant value are auto-initialized: from left to right, starting at zero or the next explicitly initialized constant, incrementing by 1. 44 45 To explicitly set enumerator values, \emph{all} enumerators must be set in \emph{ascending} order, \ie there is no auto-initialization. … … 51 52 (0, 10, RED) (1, 20, GREEN) (2, 30, BLUE) 52 53 \end{ada} 54 Note, Ada is case-\emph{insensitive} so names may appear in multiple forms and still be the same, \eg @Red@ and @RED@ (a questionable design decision). 53 55 54 56 Like C, Ada enumerators are unscoped, \ie enumerators declared inside of an enum are visible (projected) into the enclosing scope. 55 Note, Ada is case-\emph{insensitive} so names may appear in multiple forms and still be the same name (a questionable design decision). 56 The enumeration operators are the ordering operators, @=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relation is given implicitly by the sequence of enumerators, which is always ascending. 57 The enumeration operators are the ordering operators, @=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relationship is given implicitly by the sequence of enumerators, which is always ascending. 57 58 58 59 Ada enumerators are overloadable. … … 119 120 \begin{ada} 120 121 type Operator is ( '+', '-', '*', '/' ); 121 Op : Operator;122 122 \end{ada} 123 123 which is syntactic sugar for the label and not character literals from the predefined type @Character@. 124 The purpose is readability using character literals rather than names. 125 \begin{ada} 126 Op := '+'; 127 case Op is -- all enumerators must appear 128 when '+' => ... ; 129 when '-' => ... ; 130 when '*' => ... ; 131 when '/' => ... ; 132 end case; 133 \end{ada} 134 Arrays of character enumerators can be treated as strings. 124 The purpose is strictly readability using character literals rather than names. 125 \begin{ada} 126 Op : Operator := '+'; 127 if Op = '+' or else Op = '-' then ... ; 128 elsif Op = '*' or else Op = '/' then ... ; end if; 129 \end{ada} 130 Interestingly, arrays of character enumerators can be treated as strings. 135 131 \begin{ada} 136 132 Ops : array( 0..3 ) of Operator; 137 133 Ops := @"+-*/"@; -- string assignment to array elements 138 134 Ops := @"+-" & "*/"@; -- string concatenation and assignment 139 for Op of Ops loop140 Put_Line( Operator'Image( Op ) );141 end loop;142 135 \end{ada} 143 136 Ada's @Character@ type is defined as a character enumeration across all Latin-1 characters. 144 137 145 Ada's boolean type is defined asa special enumeration, which can be used in conditions.138 Ada's boolean type is also a special enumeration, which can be used in conditions. 146 139 \begin{ada} 147 140 type Boolean is (False, True); -- False / True not keywords … … 160 153 Hence, the ordering of the enumerators is crucial to provide the necessary ranges. 161 154 162 An enumeration type can be used in the Ada \lstinline[language=ada]{case} ( switch) anditerating constructs.155 An enumeration type can be used in the Ada \lstinline[language=ada]{case} (all enumerators must appear or a default) or iterating constructs. 163 156 \begin{cquote} 164 157 \lstDeleteShortInline@ … … 263 256 enum class E { A, B, C }; 264 257 E e = @E::@A; $\C{// qualified enumerator}$ 265 e = B; $\C{// B not in scope}$258 e = B; $\C{// error: B not in scope}$ 266 259 \end{c++} 267 260 \CC{20} supports explicit unscoping with a \lstinline[language=c++]{using enum} declaration. … … 278 271 enum class srgb @: signed char@ { Red = -1, Green = 0, Blue = 1 }; 279 272 \end{c++} 280 There is no implicit conversion from the \lstinline[language=c++]{enum class} type andto its declared type.273 There is no implicit conversion from the \lstinline[language=c++]{enum class} type to its declared type. 281 274 \begin{c++} 282 275 rgb crgb = rgb::Red; 283 char ch = rgb::Red; ch = crgb; $\C{// disallowed}$276 char ch = rgb::Red; ch = crgb; $\C{// error}$ 284 277 \end{c++} 285 Finally, there is no mechanism to iterate through an enumeration nor use the enumeration type to declare an array dimension. 278 Finally, enumerations can be used in the @switch@ statement but there is no mechanism to iterate through an enumeration. 279 An enumeration type cannot declare an array dimension but can be used as a subscript. 280 There is no mechanism to subtype or inherit from enumerations. 286 281 287 282 … … 292 287 % https://www.tutorialsteacher.com/codeeditor?cid=cs-mk8Ojx 293 288 294 \Csharp is a dynamically-typed programming-language with a scoped, integral enumeration-type similar to C/\CC enumeration.289 \Csharp is a dynamically-typed programming-language with a scoped, integral enumeration-type similar to the C/\CC enumeration. 295 290 \begin{csharp} 296 291 enum Weekday : byte { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun@,@ }; 297 292 \end{csharp} 298 The default underlying type is @int@, with auto-incrementing, implicit/explicit initialization, terminator comma, and optional integral typing (default @int@) 293 The default underlying type is @int@, with auto-incrementing, implicit/explicit initialization, terminator comma, and optional integral typing (default @int@). 299 294 A method cannot be defined in an enumeration type. 300 295 As well, there is an explicit bidirectional conversion between an enumeration and its integral type, and an implicit conversion to the enumerator label in display contexts. … … 306 301 \end{csharp} 307 302 308 The @Enum.GetValues@ pseudo-method retrieves an array of the enumeration constants for looping over an enumeration type or variable .303 The @Enum.GetValues@ pseudo-method retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation). 309 304 \begin{csharp} 310 305 foreach ( Weekday constant in @Enum.GetValues@( typeof(Weekday) ) ) { … … 341 336 Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 342 337 343 344 338 static bool isWeekday( Weekday wd ) { 345 return Weekday.Mon <= wd 346 && wd <= Weekday.Fri; 339 return wd <= Weekday.Fri; 347 340 } 348 341 static bool isWeekend( Weekday wd ) { 349 return Weekday.Sat <= wd 350 && wd <= Weekday.Sun; 342 return Weekday.Sat <= wd; 351 343 } 352 344 … … 363 355 \begin{csharp} 364 356 public class Program { 365 public @class@ WeekDay { 366 public enum Weekday { 367 Mon=-4, Tue=-3, Wed=-2, Thu=-1, 368 Fri=0, Sat=1, Sun=2 }; 369 Weekday day; 357 public @class@ WeekDay : Enumeration { 358 public enum Day { 359 Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 360 public enum Day2 : Day { 361 XXX, YYY }; 362 Day day; 370 363 public bool isWeekday() { 371 return day <= 0; 372 364 return day <= Day.Fri; 373 365 } 374 366 public bool isWeekend() { 375 return day > 0 376 367 return day > Day.Fri; 377 368 } 378 public WeekDay( Weekday d ) { day = d; }369 public WeekDay( Day d ) { day = d; } 379 370 } 380 371 public static void Main() { 381 372 WeekDay cday = new 382 WeekDay( WeekDay. Weekday.Sat );373 WeekDay( WeekDay.Day.Sat ); 383 374 Console.WriteLine( cday.isWeekday() ); 384 375 Console.WriteLine( cday.isWeekend() ); … … 396 387 \lstnewenvironment{Go}[1][]{\lstset{language=Go,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{} 397 388 398 Golang provides a mechanism similar to classic Pascal \lstinline[language=pascal]{const}, binding a name to a constant literal/expression (pseudo enumeration).389 Golang provides pseudo-enumeration similar to classic Pascal \lstinline[language=pascal]{const}, binding a name to a constant literal/expression. 399 390 \begin{Go} 400 391 const ( R = 0; G; B ) $\C{// implicit: 0 0 0}$ … … 448 439 449 440 for i := Mon; i <= Sun; i += 1 { 450 441 fmt.Println( i ) 451 442 } 452 443 … … 457 448 \lstMakeShortInline@ 458 449 \end{cquote} 459 The loop prints the values from 0 to 13 because there is no actual enumeration.450 However, the loop prints the values from 0 to 13 because there is no actual enumeration. 460 451 461 452 462 453 \section{Java} 463 \lstnewenvironment{Java}[1][]{\lstset{language=Java,escapechar=\$,moredelim=**[is][\color{red}]{!}{!},}\lstset{#1}}{} 454 \lstnewenvironment{Java}[1][]{\lstset{language=Java,morekeywords={enum,assert,strictfp}, 455 escapechar=\$,moredelim=**[is][\color{red}]{!}{!},}\lstset{#1}}{} 464 456 465 457 Every enumeration in Java is an enumeration class. … … 471 463 the scoped enumerators are an ordered list of @final@ methods of type integer, ordered left to right starting at 0, increasing by 1. 472 464 The value of an enumeration instance is restricted to the enumeration's enumerators. 473 There is an implicit integervariable in the enumeration used to store the value of an enumeration instance.474 The position (ordinal) and label are accessible, andthe value is the same as the position.465 There is an implicit @int@ variable in the enumeration used to store the value of an enumeration instance. 466 The position (ordinal) and label are accessible, where the value is the same as the position. 475 467 \begin{Java} 476 System.out.println( !day.ordinal()! + " " + !day! ); // 5 Sat 468 System.out.println( day.!ordinal()! + " " + day.!name()! ); // 5 Sat 469 \end{Java} 470 There is an inverse function @valueOf@ from string to enumerator. 471 \begin{Java} 472 day = Weekday.valueOf( "Wed" ); 477 473 \end{Java} 478 474 There are no implicit conversions to/from an enumerator and its underlying type. 479 480 To explicitly assign enumerator values, the enumeration must specify an explicit type in the enumeration class.481 \begin{Java}482 enum Weekday {483 Mon( -4 ), Tue( -3 ), Wed( -2 ), Thu( -1 ), Fri( 0 ), Sat( 1 ), Sun( 2 ); // must appear first484 private int day; $\C{// underlying enumeration type}$485 private Weekday( int d ) { day = d; } $\C{// used to initialize enumerators and instances}$486 };487 Weekday day = Weekday.Sat; $\C{// implicit constructor call}$488 \end{Java}489 The position, value, and label are accessible.490 \begin{Java}491 System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day! ); // 5 1 Sat492 \end{Java}493 The constructor is private so only initialization or assignment can be used to set an enumeration, which ensures only corresponding enumerator values are allowed.494 495 475 Like \Csharp, \VRef[Figure]{f:JavaFreeVersusClass} shows the same example for an enumeration with free routines for manipulation, and embedding the enumeration and operations into an enumeration class. 496 476 … … 502 482 \hline 503 483 \begin{Java} 504 public class test { 505 506 enum Weekday { 507 Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 508 509 static boolean isWeekday( Weekday wd ) { 510 return Weekday.Mon.ordinal() <= wd.ordinal() 511 && wd.ordinal() <= Weekday.Fri.ordinal(); 512 } 513 static boolean isWeekend( Weekday wd ) { 514 return Weekday.Sat.ordinal() <= wd.ordinal() 515 && wd.ordinal() <= Weekday.Sun.ordinal(); 516 } 517 518 519 public static void main( String[] args ) { 520 Weekday day = Weekday.Sat; 521 System.out.println( isWeekday( day ) ); 522 System.out.println( isWeekend( day ) ); 523 } 484 enum Weekday !{! 485 Mon, Tue, Wed, Thu, Fri, Sat, Sun !}!; 486 487 static boolean isWeekday( Weekday wd ) { 488 return wd.ordinal() <= Weekday.Fri.ordinal(); 489 } 490 static boolean isWeekend( Weekday wd ) { 491 return Weekday.Fri.ordinal() < wd.ordinal(); 492 } 493 494 public static void main( String[] args ) { 495 Weekday day = Weekday.Sat; 496 System.out.println( isWeekday( day ) ); 497 System.out.println( isWeekend( day ) ); 524 498 } 525 499 \end{Java} 526 500 & 527 501 \begin{Java} 528 public class test { 529 public !enum! WeekDay { 530 Mon(-4), Tue(-3), Wed(-2), Thu(-1), 531 Fri(0), Sat(1), Sun(2); 532 private int day; 533 public boolean isWeekday() { 534 return day <= 0; 535 536 } 537 public boolean isWeekend() { 538 return day > 0; 539 540 } 541 private WeekDay( int d ) { day = d; } 502 enum Weekday !{! 503 Mon, Tue, Wed, Thu, Fri, Sat, Sun; 504 505 public boolean isWeekday() { 506 return ordinal() <= Weekday.Fri.ordinal(); 542 507 } 543 public static void main( String[] args ) { 544 WeekDay day = WeekDay.Sat; 545 System.out.println( day.isWeekday() ); 546 System.out.println( day.isWeekend() ); 508 public boolean isWeekend() { 509 return Weekday.Fri.ordinal() < ordinal(); 547 510 } 511 !}! 512 public static void main( String[] args ) { 513 WeekDay day = WeekDay.Sat; 514 System.out.println( day.isWeekday() ); 515 System.out.println( day.isWeekend() ); 548 516 } 549 517 \end{Java} … … 553 521 \label{f:JavaFreeVersusClass} 554 522 \end{figure} 523 524 To explicitly assign enumerator values and/or use a non-@int@ enumeration type (any Java type may be used), the enumeration must specify an explicit type in the enumeration class and a constructor. 525 \begin{Java} 526 enum Weekday { 527 Mon!(1)!, Tue!(2)!, Wed!(3)!, Thu!(4)!, Fri!(5)!, Sat!(6)!, Sun!(7)!; // must appear first 528 private !long! day; $\C{// underlying enumeration type}$ 529 private Weekday( !long! d ) { day = d; } $\C{// used to initialize enumerators}$ 530 }; 531 Weekday day = Weekday.Sat; 532 \end{Java} 533 If an enumerator initialization is a runtime expression, the expression is executed once at the point the enumeration is declaraed. 534 535 The position, value, and label are accessible. 536 \begin{Java} 537 System.out.println( !day.ordinal()! + " " + !day.day! + " " + !day.name()! ); // 5 6 Sat 538 \end{Java} 539 The constructor is private so only initialization or assignment can be used to set an enumeration, which ensures only corresponding enumerator values are allowed. 555 540 556 541 An enumeration can appear in a @switch@ statement, but no ranges. … … 565 550 } 566 551 \end{Java} 567 L ooping over an enumeration is done using method @values@, which returns the array of enumerator values.552 Like \Csharp, looping over an enumeration is done using method @values@, which returns the array of enumerator values (expensive operation). 568 553 \begin{Java} 569 554 for ( Weekday iday : Weekday.values() ) { 570 System.out.println( iday.ordinal() + " " + iday + " " ); 571 } 555 System.out.print( iday.ordinal() + iday.day + " " + iday.name() + ", " ); 556 } 557 0 1 Mon, 1 2 Tue, 2 3 Wed, 3 4 Thu, 4 5 Fri, 5 6 Sat, 6 7 Sun, 572 558 \end{Java} 573 559 … … 581 567 \section{Modula-3} 582 568 569 570 583 571 \section{Rust} 572 \lstnewenvironment{rust}[1][]{\lstset{language=Rust,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{} 573 574 Enumerations 575 \begin{rust} 576 Syntax 577 Enumeration : 578 enum IDENTIFIER GenericParams? WhereClause? { EnumItems? } 579 580 EnumItems : 581 EnumItem ( , EnumItem )* ,? 582 583 EnumItem : 584 OuterAttribute* Visibility? 585 IDENTIFIER ( EnumItemTuple | EnumItemStruct )? EnumItemDiscriminant? 586 587 EnumItemTuple : 588 ( TupleFields? ) 589 590 EnumItemStruct : 591 { StructFields? } 592 593 EnumItemDiscriminant : 594 = Expression 595 \end{rust} 596 An enumeration, also referred to as an enum, is a simultaneous definition of a nominal enumerated type as well as a set of constructors, that can be used to create or pattern-match values of the corresponding enumerated type. 597 598 Enumerations are declared with the keyword enum. 599 600 An example of an enum item and its use: 601 \begin{rust} 602 enum Animal { 603 Dog, 604 Cat, 605 } 606 607 let mut a: Animal = Animal::Dog; 608 a = Animal::Cat; 609 \end{rust} 610 Enum constructors can have either named or unnamed fields: 611 \begin{rust} 612 enum Animal { 613 Dog(String, f64), 614 Cat { name: String, weight: f64 }, 615 } 616 617 let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2); 618 a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 }; 619 \end{rust} 620 In this example, Cat is a struct-like enum variant, whereas Dog is simply called an enum variant. 621 622 An enum where no constructors contain fields are called a field-less enum. For example, this is a fieldless enum: 623 \begin{rust} 624 enum Fieldless { 625 Tuple(), 626 Struct{}, 627 Unit, 628 } 629 \end{rust} 630 If a field-less enum only contains unit variants, the enum is called an unit-only enum. For example: 631 \begin{rust} 632 enum Enum { 633 Foo = 3, 634 Bar = 2, 635 Baz = 1, 636 } 637 \end{rust} 638 639 \subsection{Discriminants} 640 641 Each enum instance has a discriminant: an integer logically associated to it that is used to determine which variant it holds. 642 643 Under the default representation, the discriminant is interpreted as an isize value. However, the compiler is allowed to use a smaller type (or another means of distinguishing variants) in its actual memory layout. 644 645 \subsection{Assigning discriminant values} 646 647 \subsection{Explicit discriminants} 648 649 In two circumstances, the discriminant of a variant may be explicitly set by following the variant name with = and a constant expression: 650 651 if the enumeration is "unit-only". 652 653 if a primitive representation is used. For example: 654 \begin{rust} 655 #[repr(u8)] 656 enum Enum { 657 Unit = 3, 658 Tuple(u16), 659 Struct { 660 a: u8, 661 b: u16, 662 } = 1, 663 } 664 \end{rust} 665 666 \subsection{Implicit discriminants} 667 668 If a discriminant for a variant is not specified, then it is set to one higher than the discriminant of the previous variant in the declaration. If the discriminant of the first variant in the declaration is unspecified, then it is set to zero. 669 \begin{rust} 670 enum Foo { 671 Bar, // 0 672 Baz = 123, // 123 673 Quux, // 124 674 } 675 676 let baz_discriminant = Foo::Baz as u32; 677 assert_eq!(baz_discriminant, 123); 678 \end{rust} 679 680 \subsection{Restrictions} 681 682 It is an error when two variants share the same discriminant. 683 \begin{rust} 684 enum SharedDiscriminantError { 685 SharedA = 1, 686 SharedB = 1 687 } 688 689 enum SharedDiscriminantError2 { 690 Zero, // 0 691 One, // 1 692 OneToo = 1 // 1 (collision with previous!) 693 } 694 \end{rust} 695 It is also an error to have an unspecified discriminant where the previous discriminant is the maximum value for the size of the discriminant. 696 \begin{rust} 697 #[repr(u8)] 698 enum OverflowingDiscriminantError { 699 Max = 255, 700 MaxPlusOne // Would be 256, but that overflows the enum. 701 } 702 703 #[repr(u8)] 704 enum OverflowingDiscriminantError2 { 705 MaxMinusOne = 254, // 254 706 Max, // 255 707 MaxPlusOne // Would be 256, but that overflows the enum. 708 } 709 \end{rust} 710 711 \subsection{Accessing discriminant} 712 713 \begin{rust} 714 Via mem::discriminant 715 \end{rust} 716 mem::discriminant returns an opaque reference to the discriminant of an enum value which can be compared. This cannot be used to get the value of the discriminant. 717 Casting 718 719 If an enumeration is unit-only (with no tuple and struct variants), then its discriminant can be directly accessed with a numeric cast; e.g.: 720 \begin{rust} 721 enum Enum { 722 Foo, 723 Bar, 724 Baz, 725 } 726 727 assert_eq!(0, Enum::Foo as isize); 728 assert_eq!(1, Enum::Bar as isize); 729 assert_eq!(2, Enum::Baz as isize); 730 \end{rust} 731 Field-less enums can be casted if they do not have explicit discriminants, or where only unit variants are explicit. 732 \begin{rust} 733 enum Fieldless { 734 Tuple(), 735 Struct{}, 736 Unit, 737 } 738 739 assert_eq!(0, Fieldless::Tuple() as isize); 740 assert_eq!(1, Fieldless::Struct{} as isize); 741 assert_eq!(2, Fieldless::Unit as isize); 742 \end{rust} 743 \begin{rust} 744 #[repr(u8)] 745 enum FieldlessWithDiscrimants { 746 First = 10, 747 Tuple(), 748 Second = 20, 749 Struct{}, 750 Unit, 751 } 752 753 assert_eq!(10, FieldlessWithDiscrimants::First as u8); 754 assert_eq!(11, FieldlessWithDiscrimants::Tuple() as u8); 755 assert_eq!(20, FieldlessWithDiscrimants::Second as u8); 756 assert_eq!(21, FieldlessWithDiscrimants::Struct{} as u8); 757 assert_eq!(22, FieldlessWithDiscrimants::Unit as u8); 758 \end{rust} 759 760 \subsection{Pointer casting} 761 762 If the enumeration specifies a primitive representation, then the discriminant may be reliably accessed via unsafe pointer casting: 763 \begin{rust} 764 #[repr(u8)] 765 enum Enum { 766 Unit, 767 Tuple(bool), 768 Struct{a: bool}, 769 } 770 771 impl Enum { 772 fn discriminant(&self) -> u8 { 773 unsafe { *(self as *const Self as *const u8) } 774 } 775 } 776 777 let unit_like = Enum::Unit; 778 let tuple_like = Enum::Tuple(true); 779 let struct_like = Enum::Struct{a: false}; 780 781 assert_eq!(0, unit_like.discriminant()); 782 assert_eq!(1, tuple_like.discriminant()); 783 assert_eq!(2, struct_like.discriminant()); 784 \end{rust} 785 786 \subsection{Zero-variant enums} 787 788 Enums with zero variants are known as zero-variant enums. As they have no valid values, they cannot be instantiated. 789 \begin{rust} 790 enum ZeroVariants {} 791 \end{rust} 792 Zero-variant enums are equivalent to the never type, but they cannot be coerced into other types. 793 \begin{rust} 794 let x: ZeroVariants = panic!(); 795 let y: u32 = x; // mismatched type error 796 \end{rust} 797 798 \subsection{Variant visibility} 799 800 Enum variants syntactically allow a Visibility annotation, but this is rejected when the enum is validated. This allows items to be parsed with a unified syntax across different contexts where they are used. 801 \begin{rust} 802 macro_rules! mac_variant { 803 ($vis:vis $name:ident) => { 804 enum $name { 805 $vis Unit, 806 807 $vis Tuple(u8, u16), 808 809 $vis Struct { f: u8 }, 810 } 811 } 812 } 813 814 // Empty `vis` is allowed. 815 mac_variant! { E } 816 817 // This is allowed, since it is removed before being validated. 818 #[cfg(FALSE)] 819 enum E { 820 pub U, 821 pub(crate) T(u8), 822 pub(super) T { f: String } 823 } 824 \end{rust} 584 825 585 826 … … 587 828 \lstnewenvironment{swift}[1][]{\lstset{language=Swift,escapechar=\$,moredelim=**[is][\color{red}]{@}{@},}\lstset{#1}}{} 588 829 589 Model custom types that define a list of possible values. 830 % https://www.programiz.com/swift/online-compiler 831 832 A Swift enumeration provides a heterogenous set of enumerators, like a tagged @union@, where the field name is the enumerator and its list of type parameters form its type. 833 \begin{swift} 834 enum Many { 835 case Mon, Tue, Wed, Thu, Fri, Sat, Sun // basic enumerator 836 case code( String ) // string enumerator 837 case tuple( Int, Int, Int ) // tuple enumerator 838 }; 839 var day = Many.Sat; // qualification to resolve type 840 print( day ); 841 day = .Wed // no qualification after type resolved 842 print( day ); 843 day = .code( "ABC" ); 844 print( day ); 845 day = .tuple( 1, 2, 3 ); 846 print( day ); 847 848 Sat 849 Wed 850 code("ABC") 851 tuple(1, 2, 3) 852 \end{swift} 853 590 854 591 855 An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code. … … 607 871 \paragraph{Enumeration Syntax} 608 872 609 You introduce enumerations with the @enum@ keyword and place their entire definition within a pair of braces:610 \begin{swift}611 enum SomeEnumeration {612 // enumeration definition goes here613 }614 \end{swift}615 Here's an example for the four main points of a compass:616 \begin{swift}617 enum CompassPoint {618 case north619 case south620 case east621 case west622 }623 \end{swift}624 The values defined in an enumeration (such as @north@, @south@, @east@, and @west@) are its enumeration cases.625 You use the @case@ keyword to introduce new enumeration cases.626 873 627 874 Note:
Note: See TracChangeset
for help on using the changeset viewer.