R.init if no handler matches.var.visit
auto visit(handlers...)() scope const @safeApply a visitor pattern to this value, dispatching to the appropriate handler based on type.
This provides type-safe dispatch without manual switch on Type, similar to std.variant.visit. Handlers are provided as template arguments and can be lambdas, function pointers, or delegates.
Handler Selection:
- Handlers accepting specific types (bool, long, double, string, var[], var[string]) are matched first.
- A handler accepting
varserves as a catch-all fallback. - If no matching handler is found for the current type, returns the default value of the return type.
Type Mapping:
- NULL: matched by
typeof(null)handler or fallback - BOOL: matched by
boolhandler - Integer types (BYTE..ULONG): matched by
longhandler (widened).ULONGvalues abovelong.maxare matched by aulonghandler first; if only alonghandler exists it sees the (wrapped) value through D's implicit conversion. - Floating types (FLOAT, DOUBLE, REAL): matched by
doublehandler (widened) - STRING: matched by
stringhandler - ARRAY: matched by
var[]handler - OBJECT: matched by
var[string]handler - Character types (CHAR, WCHAR, DCHAR): matched by
dcharhandler (widened)
Fallback normalization (documented behavior, intentional): the var-typed fallback does not receive the original receiver. It sees a normalized reboxed value following the same widening as typed handlers: narrow integer tags become LONG (a BYTE receiver arrives as LONG), FLOAT becomes DOUBLE, and characters may arrive reboxed after typed dispatch. A fallback handler therefore cannot inspect the receiver's original narrow tag and may not compare equal to the original under exact-tag equality. visitNogc shares the typed-handler widening. Because the fallback value is an independent copy (deep for const receivers), mutating it cannot affect the receiver.
Parameters
handlers | One or more callable handlers for different types. |
Returns
Examples
var v = 42;
string result = v.visit!(
(long n) => "integer: " ~ n.to!string,
(string s) => "string: " ~ s,
(var fallback) => "other: " ~ fallback.toString()
);
assert(result == "integer: 42");
var s = "hello";
auto r = s.visit!(
(long n) => n * 2,
(string str) => cast(long)str.length
);
assert(r == 5); // length of "hello"