Declarations
Operator declarations
Define operators on a class or struct by declaring a member with a symbolic selector such as (+), (==) or ([]).
since 0.1.0-alpha.1linuxwindowswasm
Description
A class or struct gives meaning to an operator by declaring a member whose name is the operator in parentheses. The result type comes first and the right-hand operand is the parameter:
Money (+)(Money other) => Money(cents + other.cents);
bool (==)(Money other) => cents == other.cents;
With such a member, a + b calls (+) on a's class, selecting the overload by the type of b.
Write the selector without spaces: (==), (<=), ([]). A selector with spaces inside the
parentheses declares a member that no expression ever calls.
(==) must return bool. != needs no declaration of its own; it is the negation of ==. Other
comparisons are only available if you declare them, and a comparison that is not declared throws a
RuntimeException at run time.
Operators on a class
class Money {
int cents;
Money (+)(Money other) => Money(cents + other.cents);
Money (-)(Money other) => Money(cents - other.cents);
Money (*)(int k) => Money(cents * k);
bool (==)(Money other) => cents == other.cents;
bool (<)(Money other) => cents < other.cents;
string show() => cents.toString() + "c";
}
Money a = Money(150);
Money b = Money(250);
console.writeln((a + b).show());
console.writeln((b - a).show());
console.writeln((a * 3).show());
console.writeln(a == Money(150));
console.writeln(a != b);
console.writeln(a < b);
400c
100c
450c
true
true
true
Rules
- An operator is a member declared as
ReturnType (op)(Type other) body. - The operators that can be declared are
+ - * / % == != < <= > >= << >> ^, and the index operator([]), which is declared as an accessor (seelang.accessors). - A binary expression
a op bcalls the(op)member ofa's class. The right operand's type selects among overloads of the same operator. (==)returnsbool. Declaring(==)also provides!=as its negation;!=can be declared explicitly instead.- No other operator is derived from another: declaring
(<)does not provide>or<=. - A comparison or arithmetic operator that the class does not declare throws a
RuntimeExceptionwhen the expression is evaluated. - A struct has a derived
==and!=when all its fields are comparable (seelang.structs); an explicit(==)replaces the derived one. - The selector is written without whitespace inside the parentheses.
Examples
A set of operators that cover the arithmetic and comparison operators:
More operators
class V {
int n;
V (/)(int k) => V(n / k);
V (%)(int k) => V(n % k);
bool (>)(V o) => n > o.n;
bool (>=)(V o) => n >= o.n;
bool (!=)(V o) => n != o.n;
V (<<)(int k) => V(n << k);
V (>>)(int k) => V(n >> k);
V (^)(V o) => V(n + o.n);
}
V a = V(20);
V b = V(7);
console.writeln((a / 4).n);
console.writeln((a % 6).n);
console.writeln(a > b);
console.writeln(a >= b);
console.writeln(a != b);
console.writeln((a << 1).n);
console.writeln((a >> 1).n);
console.writeln((a ^ b).n);
5
2
true
true
true
40
10
27
An operator may be overloaded on the right operand's type:
Overloading an operator by operand type
class Money {
int cents;
Money (+)(Money other) => Money(cents + other.cents);
Money (+)(int extra) => Money(cents + extra);
}
Money a = Money(150);
console.writeln((a + 5).cents); // 155
console.writeln((a + Money(7)).cents); // 157
See also
- Methods and functions — Declare callables with block or single-statement bodies, overloads, default parameters, named arguments and type parameters.
- Accessors — Replace how a field is read or written with get and set, and define computed values and indexers.
- Value structs — Declare value types that are copied on every assignment, pass and return, with derived equality and explicit mutating methods.