Next: Operators, Previous: Files, Up: Programming
Users may also define their own data types as structures, along with
user-defined operators, much as in C++. By default, structure members
are public
(may be read and modified anywhere in the code), but may be
optionally declared restricted
(readable anywhere but writeable
only inside the structure where they are defined) or private
(readable and writable only inside the structure). The virtual
structure this
refers to the enclosing structure. Any code at the
top-level scope within the structure is executed on initialization.
A default initializer for a structure S
can be defined by
creating a function S operator init()
. This can be used to
initialize each instance of S
with new S
(which creates
a new anonymous instance of S
).
struct S { public real a=1; real f(real a) {return a+this.a;} } S operator init() {return new S;} S s; // Initializes s with S operator init(); write(s.f(2)); // Outputs 3 S operator + (S s1, S s2) { S result; result.a=s1.a+s2.a; return result; } write((s+s).f(0)); // Outputs 2
In the following example, the static function T.T(real x)
is a constructor that initializes and returns a new instance of T
:
struct T { real x; static T T(real x) {T t=new T; t.x=x; return t;} } T operator init() {return new T;} T a; T b=T.T(1); write(a.x); // Outputs 0 write(b.x); // Outputs 1The name of the constructor need not be identical to the name of the structure; for example, see
triangle.SAS
in geometry.asy
.
Structure assignment does a shallow copy; a deep copy requires writing
an explicit copy()
member. The function bool alias(T,T)
checks to
see if two instances of the structure T
are identical.
The boolean operators ==
and !=
are by default equivalent to
alias
and !alias
respectively, but may be overwritten
for a particular type do a deep comparison.
When a
is defined both as a variable and a type, the qualified
name a.b
refers to the variable instead of the type.
Much like in C++, casting (see Casts) provides for an elegant implementation of structure inheritance, including virtual functions:
struct parent { real x=1; public void virtual(int) {write (0);} void f() {virtual(1);} } parent operator init() {return new parent;} void write(parent p) {write(p.x);} struct child { parent parent; real y=2; void virtual(int x) {write (x);} parent.virtual=virtual; void f()=parent.f; } parent operator cast(child child) {return child.parent;} child operator init() {return new child;} parent p; child c; write(c); // Outputs 1; p.f(); // Outputs 0; c.f(); // Outputs 1; write(c.parent.x); // Outputs 1; write(c.y); // Outputs 2;
Further examples of structures are Legend
and picture
in
the Asymptote
base module plain
.