-
-
Notifications
You must be signed in to change notification settings - Fork 9
constructor
IsaacShelton edited this page Nov 16, 2022
·
6 revisions
Constructors can be defined using the constructor keyword.
import basics
import random
pragma ignore_unused
struct Person (name String, uid int) {
constructor(name String){
this.name = name
this.uid = randomInt(100)
}
}
func toString(person Person) String {
return person.name + " : id=" + person.uid
}
func main {
randomize()
john Person("John") // constructed (living on stack)
james *Person = new Person("John") // constructed (living on heap)
defer delete james
print("Constructed people:")
print(john)
print(*james)
// --------- vs ---------
uninitialized_guy Person = undef // undefined (living on stack)
uninitialized_heap_guy *Person = new undef Person // undefined (living on heap)
defer delete uninitialized_heap_guy
unconstructed_guy Person // zero-initialized (living on stack)
unconstructed_heap_guy *Person = new Person // zero-initialized (living on heap)
defer delete unconstructed_heap_guy
print("Unconstructed people")
print(unconstructed_guy)
print(*unconstructed_heap_guy)
print("Uninitialized people")
print("(cannot print these, since their names would be garbage memory)")
}
You can also call a constructor like any other method, using value.__constructor__(arg1, arg2, argN). However, you are responsible for making sure the memory of the value is zero-initialized before-hand, since constructors are allowed to assume zero-initialization.
import basics
struct MyInteger (value int) {
constructor(){
this.value = 12435
}
}
func main {
my_integer MyInteger
my_integer.__constructor__()
// which is equivalent to
/*
my_integer MyInteger()
*/
// -----------------------------
print(my_integer.value)
}
Calling __constructor__ on memory that is not zero-initialized is type-dependant. Types are NOT REQUIRED to be able to be constructed on non zero-initialized memory. If uncertain, zero-initialize the memory before manual construction using something like memset(memory, 0, size_in_bytes)!
import basics
struct Person (name String, level int) {
constructor(name String){
this.name = name
this.level = 1
}
}
func main(){
// Example of manually constructing values from garbage memory
count usize = 100
raw_memory *Person = new undef Person * count // equivalent to `malloc(sizeof Person * count)`
repeat count {
person *Person = &raw_memory[idx]
memset(person, 0, sizeof Person)
person.__constructor__("Abby")
}
each Person in [raw_memory, count] {
printf("[%d] Hello %S\n", idx, it.name)
}
defer {
each Person in [raw_memory, count], it.__defer__() // destroy each person (necessary because it contains `String` and so is not POD (plain-old-data))
delete raw_memory // equivalent to `free(raw_memory)`
}
}