Created
February 3, 2021 13:34
-
-
Save leveled/db7c93056872257799a93ea021e53b78 to your computer and use it in GitHub Desktop.
Complex variable types in nim
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #Type with enum | |
| type | |
| Direction = enum | |
| north, east, south, west | |
| var x = south # `x` is of type `Direction`; its value is `south` | |
| echo x # writes "south" to `stdout` | |
| #Subrange | |
| type | |
| MySubrange = range[0..5] | |
| #Set | |
| type | |
| CharSet = set[char] | |
| var | |
| x: CharSet | |
| x = {'a'..'z', '0'..'9'} # This constructs a set that contains the | |
| # letters from 'a' to 'z' and the digits | |
| # from '0' to '9' | |
| #Bit Fields | |
| type | |
| MyFlag* {.size: sizeof(cint).} = enum | |
| A | |
| B | |
| C | |
| D | |
| MyFlags = set[MyFlag] | |
| proc toNum(f: MyFlags): int = cast[cint](f) | |
| proc toFlags(v: int): MyFlags = cast[MyFlags](v) | |
| assert toNum({}) == 0 | |
| assert toNum({A}) == 1 | |
| assert toNum({D}) == 8 | |
| assert toNum({A, C}) == 5 | |
| assert toFlags(0) == {} | |
| assert toFlags(7) == {A, B, C} | |
| #Arrays | |
| type | |
| IntArray = array[0..5, int] # an array that is indexed with 0..5 | |
| var | |
| x: IntArray | |
| x = [1, 2, 3, 4, 5, 6] | |
| for i in low(x)..high(x): | |
| echo x[i] | |
| type | |
| Direction = enum | |
| north, east, south, west | |
| BlinkLights = enum | |
| off, on, slowBlink, mediumBlink, fastBlink | |
| LevelSetting = array[north..west, BlinkLights] | |
| var | |
| level: LevelSetting | |
| level[north] = on | |
| level[south] = slowBlink | |
| level[east] = fastBlink | |
| echo repr(level) # --> [on, fastBlink, slowBlink, off] | |
| echo low(level) # --> north | |
| echo len(level) # --> 4 | |
| echo high(level) # --> west | |
| type | |
| LightTower = array[1..10, LevelSetting] | |
| var | |
| tower: LightTower | |
| tower[1][north] = slowBlink | |
| tower[1][east] = mediumBlink | |
| echo len(tower) # --> 10 | |
| echo len(tower[1]) # --> 4 | |
| echo repr(tower) # --> [[slowBlink, mediumBlink, ...more output.. | |
| # The following lines don't compile due to type mismatch errors | |
| #tower[north][east] = on | |
| #tower[0][1] = on | |
| #Sequences | |
| var | |
| x: seq[int] # a reference to a sequence of integers | |
| x = @[1, 2, 3, 4, 5, 6] # the @ turns the array into a sequence allocated on the heap | |
| #Open Arrays | |
| var | |
| fruits: seq[string] # reference to a sequence of strings that is initialized with '@[]' | |
| capitals: array[3, string] # array of strings with a fixed size | |
| capitals = ["New York", "London", "Berlin"] # array 'capitals' allows assignment of only three elements | |
| fruits.add("Banana") # sequence 'fruits' is dynamically expandable during runtime | |
| fruits.add("Mango") | |
| proc openArraySize(oa: openArray[string]): int = | |
| oa.len | |
| assert openArraySize(fruits) == 2 # procedure accepts a sequence as parameter | |
| assert openArraySize(capitals) == 3 # but also an array type | |
| #Varargs | |
| proc myWriteln(f: File, a: varargs[string]) = | |
| for s in items(a): | |
| write(f, s) | |
| write(f, "\n") | |
| myWriteln(stdout, "abc", "def", "xyz") | |
| # is transformed by the compiler to: | |
| myWriteln(stdout, ["abc", "def", "xyz"]) | |
| #Slices | |
| var | |
| a = "Nim is a programming language" | |
| b = "Slices are useless." | |
| echo a[7 .. 12] # --> 'a prog' | |
| b[11 .. ^2] = "useful" | |
| echo b # --> 'Slices are useful.' | |
| #Objects | |
| type | |
| Person = object | |
| name: string | |
| age: int | |
| var person1 = Person(name: "Peter", age: 30) | |
| echo person1.name # "Peter" | |
| echo person1.age # 30 | |
| var person2 = person1 # copy of person 1 | |
| person2.age += 14 | |
| echo person1.age # 30 | |
| echo person2.age # 44 | |
| # the order may be changed | |
| let person3 = Person(age: 12, name: "Quentin") | |
| # not every member needs to be specified | |
| let person4 = Person(age: 3) | |
| # unspecified members will be initialized with their default | |
| # values. In this case it is the empty string. | |
| doAssert person4.name == "" | |
| #Exported object | |
| type | |
| Person* = object # the type is visible from other modules | |
| name*: string # the field of this type is visible from other modules | |
| age*: int | |
| #Tuples | |
| type | |
| # type representing a person: | |
| # A person consists of a name and an age. | |
| Person = tuple | |
| name: string | |
| age: int | |
| # Alternative syntax for an equivalent type. | |
| PersonX = tuple[name: string, age: int] | |
| # anonymous field syntax | |
| PersonY = (string, int) | |
| var | |
| person: Person | |
| personX: PersonX | |
| personY: PersonY | |
| person = (name: "Peter", age: 30) | |
| # Person and PersonX are equivalent | |
| personX = person | |
| # Create a tuple with anonymous fields: | |
| personY = ("Peter", 30) | |
| # A tuple with anonymous fields is compatible with a tuple that has | |
| # field names. | |
| person = personY | |
| personY = person | |
| # Usually used for short tuple initialization syntax | |
| person = ("Peter", 30) | |
| echo person.name # "Peter" | |
| echo person.age # 30 | |
| echo person[0] # "Peter" | |
| echo person[1] # 30 | |
| # You don't need to declare tuples in a separate type section. | |
| var building: tuple[street: string, number: int] | |
| building = ("Rue del Percebe", 13) | |
| echo building.street | |
| # The following line does not compile, they are different tuples! | |
| #person = building | |
| # --> Error: type mismatch: got (tuple[street: string, number: int]) | |
| # but expected 'Person' | |
| #Reference object | |
| type | |
| Node = ref object | |
| le, ri: Node | |
| data: int | |
| var | |
| n: Node | |
| new(n) | |
| n.data = 9 | |
| # no need to write n[].data; in fact n[].data is highly discouraged! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment