std.exception
В этом модуле определены функции, связанные с исключениями и обработкой ошибок в общем случае. Также определены функции, предназначенные для помощи в тестировании юнит-тестами.
| Категория | Функции |
|---|---|
| Предположения | assertNotThrown assertThrown assumeUnique assumeWontThrow mayPointTo |
| Принудительное выполнение | doesPointTo enforce errnoEnforce |
| Обработчики | collectException collectExceptionMsg ifThrown handle |
| Прочие | basicExceptionCtors emptyExceptionMsg ErrnoException RangePrimitive |
- Лицензия:
- Boost License 1.0
- Авторы:
- Andrei Alexandrescu и Jonathan M Davis
- Источник
- std/exception.d
- Примеры:
- Описание
import core.stdc.stdlib : malloc, free; import std.algorithm.comparison : equal; import std.algorithm.iteration : map, splitter; import std.algorithm.searching : endsWith; import std.conv : ConvException, to; import std.range : front, retro; // use enforce like assert int a = 3; enforce(a > 2, "a needs to be higher than 2."); // enforce can throw a custom exception enforce!ConvException(a > 2, "a needs to be higher than 2."); // enforce will return it's input enum size = 42; auto memory = enforce(malloc(size), "malloc failed")[0 .. size]; scope(exit) free(memory.ptr); // collectException can be used to test for exceptions Exception e = collectException("abc".to!int); assert(e.file.endsWith("conv.d")); // and just for the exception message string msg = collectExceptionMsg("abc".to!int); writeln(msg); // "Unexpected 'a' when converting from type string to type int" // assertThrown can be used to assert that an exception is thrown assertThrown!ConvException("abc".to!int); // ifThrown can be used to provide a default value if an exception is thrown writeln("x".to!int().ifThrown(0)); // 0 // handle is a more advanced version of ifThrown for ranges auto r = "12,1337z32,54".splitter(',').map!(a => to!int(a)); auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0); assert(h.equal([12, 0, 54])); assertThrown!ConvException(h.retro.equal([54, 0, 12])); // basicExceptionCtors avoids the boilerplate when creating custom exceptions static class MeaCulpa : Exception { mixin basicExceptionCtors; } e = collectException((){throw new MeaCulpa("diagnostic message");}()); writeln(e.msg); // "diagnostic message" writeln(e.file); // __FILE__ writeln(e.line); // __LINE__ - 3 // assumeWontThrow can be used to cast throwing code into `nothrow` void exceptionFreeCode() nothrow { // auto-decoding only throws if an invalid UTF char is given assumeWontThrow("abc".front); } // assumeUnique can be used to cast mutable instance to an `immutable` one // use with care char[] str = " mutable".dup; str[0 .. 2] = "im"; immutable res = assumeUnique(str); writeln(res); // "immutable"
- auto assertNotThrown(T : Throwable = Exception, E)(lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__);
-
Утверждает, что заданный выражение не вызывает заданный тип
Throwable. Если выбрасываетсяThrowableзаданного типа, он перехватывается и не выходит за пределы assertNotThrown. Вместо этого выбрасываетсяAssertError. Однако любые другиеThrowableбудут выходить за пределы.- Параметры:
T Тип Throwableдля проверки.E expressionВыражение для проверки. string msgНеобязательное сообщение для вывода при ошибке теста. Если msg пусто, а у исключения, вызванного исключением, есть поле msg отличное от пустого, поле msg исключения будет выведено при ошибке теста. string fileФайл, в котором произошла ошибка. По умолчанию __FILE__.size_t lineСтрока, в которой произошла ошибка. По умолчанию __LINE__.
- Исключения:
-
AssertErrorесли заданныйThrowableвыброшен.
- Возвращает:
- результат
expression.
- Примеры:
-
import core.exception : AssertError; import std.string; assertNotThrown!StringException(enforce!StringException(true, "Error!")); //Exception is the default. assertNotThrown(enforce!StringException(true, "Error!")); assert(collectExceptionMsg!AssertError(assertNotThrown!StringException( enforce!StringException(false, "Error!"))) == `assertNotThrown failed: StringException was thrown: Error!`);
- void assertThrown(T : Throwable = Exception, E)(lazy E expression, string msg = null, string file = __FILE__, size_t line = __LINE__);
-
Утверждает, что заданное выражение выбрасывает исключение заданного типа
Throwable.Throwableперехватывается и не выходит за пределы assertThrown. Однако любые другиеThrowableбудут выходить за пределы, и если исключение заданного типа не выброшено, то будет выброшеноAssertError.- Параметры:
T Тип Throwableдля проверки.E expressionВыражение для проверки. string msgНеобязательное сообщение для вывода при ошибке теста. string fileФайл, в котором произошла ошибка. По умолчанию __FILE__.size_t lineСтрока, в которой произошла ошибка. По умолчанию __LINE__.
- Исключения:
-
AssertErrorесли заданныйThrowableне выброшен.
- Примеры:
-
import core.exception : AssertError; import std.string; assertThrown!StringException(enforce!StringException(false, "Error!")); //Exception is the default. assertThrown(enforce!StringException(false, "Error!")); assert(collectExceptionMsg!AssertError(assertThrown!StringException( enforce!StringException(true, "Error!"))) == `assertThrown failed: No StringException was thrown.`);
- template enforce(E : Throwable = Exception) if (is(typeof(new E("", string.init, size_t.init)) : Throwable) || is(typeof(new E(string.init, size_t.init)) : Throwable))
T enforce(T, Dg, string file = __FILE__, size_t line = __LINE__)(T value, scope Dg dg)
Constraints: if (isSomeFunction!Dg && is(typeof(dg())) && is(typeof(() { if (!value) { } } )));
T enforce(T)(T value, lazy Throwable ex); -
Проверяет, что заданное значение истинно. Если заданное значение ложно, выбрасывается исключение.
-
msg- сообщение об ошибке в видеstring -
dg- пользовательский делегат, возвращающий строку и вызываемый только при возникновении исключения -
ex- пользовательское исключение для выбрасывания. Оноlazyи создаётся только при возникновении исключения
- Параметры:
T valueЗначение для проверки. E Тип исключения, который будет выброшен, если значение ложно. const(char)[] msg Сообщение об ошибке для включения в исключение, если оно будет выброшено. Dg dgДелегат, который будет вызван, если значение ложно. Throwable exИсключение, которое будет выброшено, если значение ложно. string file Файл источника вызывающей функции. size_t line Номер строки вызывающей функции.
- Возвращает:
-
value, еслиcast(bool) valueистинно. В противном случае, в зависимости от выбранной перегрузки, выбрасываетсяnew Exception(msg),dg()илиex.
- Примечание
-
enforceиспользуется для выбрасывания исключений и поэтому предназначен для обработки ошибок. Он не предназначен для проверки логики вашей программы. Для этого предназначенassert. Также не используйтеenforceвнутри контрактов (т.е. внутриinиoutблоков иinvariant), потому что контракты компилируются при компиляции с -release.
Dg.- Примеры:
-
import core.stdc.stdlib : malloc, free; import std.conv : ConvException, to; // use enforce like assert int a = 3; enforce(a > 2, "a needs to be higher than 2."); // enforce can throw a custom exception enforce!ConvException(a > 2, "a needs to be higher than 2."); // enforce will return it's input enum size = 42; auto memory = enforce(malloc(size), "malloc failed")[0 .. size]; scope(exit) free(memory.ptr);
- Примеры:
-
assertNotThrown(enforce(true, new Exception("this should not be thrown"))); assertThrown(enforce(false, new Exception("this should be thrown")));
- Примеры:
-
writeln(enforce(123)); // 123 try { enforce(false, "error"); assert(false); } catch (Exception e) { writeln(e.msg); // "error" writeln(e.file); // __FILE__ writeln(e.line); // __LINE__ - 7 }
- Примеры:
- Алиасите вашу собственную функцию enforce
import std.conv : ConvException; alias convEnforce = enforce!ConvException; assertNotThrown(convEnforce(true)); assertThrown!ConvException(convEnforce(false, "blah"));
- T enforce(T)(T value, lazy const(char)[] msg = null, string file = __FILE__, size_t line = __LINE__)
Constraints: if (is(typeof(() { if (!value) { } } )));
-
- alias errnoEnforce = enforce!(ErrnoException).enforce(T)(T value, lazy const(char)[] msg = null, string file = __FILE__, size_t line = __LINE__) if (is(typeof(() { if (!value) { } } )));
-
Проверяет, что заданное значение истинно, выбрасывая
ErrnoExceptionесли это не так.- Параметры:
T value Значение для проверки. const(char)[] msg Сообщение для включения в ErrnoExceptionесли оно выбрасывается.
- Возвращает:
-
value, еслиcast(bool) valueистинно. В противном случае выбрасываетсяnew ErrnoException(msg). Предполагается, что последняя операция установилаerrnoв код ошибки, соответствующий невыполнению условия.
- Примеры:
-
import core.stdc.stdio : fclose, fgets, fopen; import std.file : thisExePath; import std.string : toStringz; auto f = fopen(thisExePath.toStringz, "r").errnoEnforce; scope(exit) fclose(f); char[100] buf; auto line = fgets(buf.ptr, buf.length, f); enforce(line !is null); // expect a non-empty line
- template enforceEx(E : Throwable) if (is(typeof(new E("", string.init, size_t.init))))
-
Устарело. Пожалуйста, используйте
enforceвместо этого. Эта функция будет удалена в версии 2.089.Если
!valueравноfalse, возвращаетсяvalue. В противном случае выбрасываетсяnew E(msg, file, line). Или еслиEне принимает сообщение и может быть сконструирован сnew E(file, line), то будет выброшеноnew E(file, line).- Пример
auto f = enforceEx!FileMissingException(fopen("data.txt")); auto line = readln(f); enforceEx!DataCorruptionException(line.length);- T enforceEx(T)(T value, lazy string msg = "", string file = __FILE__, size_t line = __LINE__);
-
То же самое
- T collectException(T = Exception, E)(lazy E expression, ref E result);
-
Перехватывает и возвращает исключение, выброшенное из заданного выражения. Если исключение не выбрасывается, то возвращается null, а
resultустанавливается в результат выражения.Обратите внимание, что хотя
collectExceptionможет использоваться для сбора любыхThrowableи не толькоExceptions, в целом не рекомендуется перехватывать что-либо, что не являетсяExceptionили типом, производным отException. Поэтому не используйтеcollectExceptionдля сбора не-Exceptions, если вы не уверены, что это то, что вы действительно хотите сделать.- Параметры:
T Тип исключения для перехвата. E expressionВыражение, которое может выбросить исключение. E resultРезультат выражения, если исключение не выбрасывается.
- Примеры:
-
int b; int foo() { throw new Exception("blah"); } assert(collectException(foo(), b)); int[] a = new int[3]; import core.exception : RangeError; assert(collectException!RangeError(a[4], b));
- T collectException(T : Throwable = Exception, E)(lazy E expression);
-
Перехватывает и возвращает исключение, выброшенное из заданного выражения. Если исключение не выбрасывается, возвращается null.
Eможет бытьvoid.Обратите внимание, что хотя
collectExceptionможет использоваться для сбора любыхThrowableи не толькоExceptions, в целом не рекомендуется перехватывать что-либо, что не являетсяExceptionили типом, производным отException. Поэтому не используйтеcollectExceptionдля сбора не-Exceptions, если вы не уверены, что это то, что вы действительно хотите сделать.- Параметры:
T Тип исключения для перехвата. E expressionВыражение, которое может выбросить исключение.
- Примеры:
-
int foo() { throw new Exception("blah"); } writeln(collectException(foo()).msg); // "blah"
- string collectExceptionMsg(T = Exception, E)(lazy E expression);
-
Перехватывает исключение, выброшенное из заданного выражения, и возвращает свойство msg этого исключения. Если исключение не выбрасывается, возвращается null.
Eможет бытьvoid.Если исключение выброшено, но оно имеет пустое сообщение, возвращается
emptyExceptionMsg.
Обратите внимание, что хотяcollectExceptionMsgможет использоваться для сбора любыхThrowableи не толькоExceptions, в целом не рекомендуется перехватывать что-либо, что не являетсяExceptionили типом, производным отException. Поэтому не используйтеcollectExceptionMsgдля сбора не-Exceptions, если вы не уверены, что это то, что вы действительно хотите сделать.- Параметры:
T Тип исключения для перехвата. E expressionВыражение, которое может выбросить исключение.
- Примеры:
-
void throwFunc() { throw new Exception("My Message."); } writeln(collectExceptionMsg(throwFunc())); // "My Message." void nothrowFunc() {} assert(collectExceptionMsg(nothrowFunc()) is null); void throwEmptyFunc() { throw new Exception(""); } writeln(collectExceptionMsg(throwEmptyFunc())); // emptyExceptionMsg
- enum string emptyExceptionMsg;
-
Значение, которое collectExceptionMsg возвращает, когда перехватывает исключение с пустым сообщением об исключении.
- pure nothrow immutable(T)[] assumeUnique(T)(T[] array);
pure nothrow immutable(T)[] assumeUnique(T)(ref T[] array);
pure nothrow immutable(T[U]) assumeUnique(T, U)(ref T[U] array); -
Преобразует изменяемый массив в неизменяемый массив идиоматичным способом. Технически,
assumeUniqueпросто вставляет преобразование, но его имя документирует предположения со стороны вызывающего кода.assumeUnique(arr)следует вызывать только тогда, когда больше нет активных изменяемых ссылок на элементыarr. Для усиления этого предположения,assumeUnique(arr)также очищаетarrперед возвратом. В сущностиassumeUnique(arr)указывает обязательство вызывающего кода о том, что больше нет изменяемого доступа к элементамarr(переходно), и что все будущие обращения будут выполняться через возвращаемый неизменяемый массивassumeUnique.Обычно
assumeUniqueиспользуется для возвращения массивов из функций, которые их выделили и построили.- Параметры:
T[] arrayМассив, который нужно преобразовать в неизменяемый.
- Возвращает:
- Неизменяемый массив.
- Пример
string letters() { char[] result = new char['z' - 'a' + 1]; foreach (i, ref e; result) { e = cast(char)('a' + i); } return assumeUnique(result); }Использование в примере выше верно, потому чтоresultбыло приватным дляlettersи недоступно для записи после возврата функции. Следующий пример показывает неправильное использованиеassumeUnique.- Неправильно
private char[] buffer; string letters(char first, char last) { if (first >= last) return null; // fine auto sneaky = buffer; sneaky.length = last - first + 1; foreach (i, ref e; sneaky) { e = cast(char)('a' + i); } return assumeUnique(sneaky); // BAD }Пример выше создаёт проблемы в клиентском коде, потому что он изменяет массивы, которые вызывающий код посчитал неизменяемыми. Для получения неизменяемого массива из изменяемого массиваbuffer, замените последнюю строку на:return to!(string)(sneaky); // not that sneaky anymore
Вызов будет дублировать массив должным образом. Обратите внимание, что проверка уникальности во время компиляции возможна в определённых случаях, особенно когда функция помечена как чистая функция. Следующий пример не нуждается в вызове assumeUnique, потому что компилятор может определить уникальность массива в чистой функции:string letters() pure { char[] result = new char['z' - 'a' + 1]; foreach (i, ref e; result) { e = cast(char)('a' + i); } return result; }Дополнительные сведения об определении уникальности см. в ключевых словах unique и lent в языке ArchJava. Недостатком использования соглашения о примененииassumeUniqueявляется то, что в настоящее время нет формальной проверки корректности предположения; с другой стороны, идиоматическое использованиеassumeUniqueпростое и достаточно редкое, чтобы быть терпимым.- Примеры:
-
int[] arr = new int[1]; auto arr1 = arr.assumeUnique; static assert(is(typeof(arr1) == immutable(int)[])); writeln(arr); // null writeln(arr1); // [0]
- Примеры:
-
int[string] arr = ["a":1]; auto arr1 = arr.assumeUnique; static assert(is(typeof(arr1) == immutable(int[string]))); writeln(arr); // null writeln(arr1.keys); // ["a"]
- nothrow T assumeWontThrow(T)(lazy T expr, string msg = null, string file = __FILE__, size_t line = __LINE__);
-
Оборачивает потенциально выбрасывающее выражение в обёртку
nothrowтаким образом, что его можно вызвать из функцииnothrow.Эта функция-обёртка документирует обязательство со стороны вызывающего кода о том, что были предприняты необходимые шаги для предотвращения любых условий, которые могут вызвать исключение во время вычисления
expr. Если окажется, что выражение выбрасывает исключение во время выполнения, обёртка выбросит исключениеAssertError.
(Обратите внимание, что объектыThrowableтакие какAssertError, которые не являются подклассомException, могут быть выброшены даже из функцийnothrow, поскольку они считаются серьёзными проблемами во время выполнения, из которых невозможно восстановиться.)- Параметры:
T exprВыражение, которое, как утверждается, не выбросит исключение. string msgСообщение, которое следует включить в AssertErrorесли предположение окажется ложным.string fileИмя файла вызывающего кода. size_t lineНомер строки вызывающего кода.
- Возвращает:
- Значение
expr, если таковое имеется.
- Примеры:
-
import std.math : sqrt; // This function may throw. int squareRoot(int x) { if (x < 0) throw new Exception("Tried to take root of negative number"); return cast(int) sqrt(cast(double) x); } // This function never throws. int computeLength(int x, int y) nothrow { // Since x*x + y*y is always positive, we can safely assume squareRoot // won't throw, and use it to implement this nothrow function. If it // does throw (e.g., if x*x + y*y overflows a 32-bit value), then the // program will terminate. return assumeWontThrow(squareRoot(x*x + y*y)); } writeln(computeLength(3, 4)); // 5
- pure nothrow @nogc @trusted bool doesPointTo(S, T, Tdummy = void)(auto ref const S source, ref const T target)
Constraints: if (__traits(isRef, source) || isDynamicArray!S || isPointer!S || is(S == class));
pure nothrow @trusted bool doesPointTo(S, T)(auto ref const shared S source, ref const shared T target);
pure nothrow @trusted bool mayPointTo(S, T, Tdummy = void)(auto ref const S source, ref const T target)
Constraints: if (__traits(isRef, source) || isDynamicArray!S || isPointer!S || is(S == class));
pure nothrow @trusted bool mayPointTo(S, T)(auto ref const shared S source, ref const shared T target); -
Проверяет, содержит ли объект source указатели или ссылки на объект target.
- Параметры:
S sourceОбъект source T targetОбъект target
- Ошибки:
- Функция явно помечена
@nogcиз-за возможного сбоя вывода, см. проблему 17084.
- Возвращает:
-
trueесли представлениеsourceсодержит указатель, который указывает на представлениеtargetили где-то внутри него. Еслиsourceявляется или содержит динамический массив, то эти функции проверяют, есть ли перекрытие между динамическим массивом и представлениемtarget. Еслиsourceявляется классом, то он будет обрабатываться как указатель. Еслиtargetявляется указателем, динамическим массивом или классом, то эти функции проверяют только, указывает лиsourceнаtarget, а не на то, что ссылаетсяtarget. Еслиsourceявляется или содержит объединение илиvoid[n], могут возникнуть либо ложные срабатывания, либо ложные отказы:doesPointToвернётtrue, если абсолютно точно, чтоsourceуказывает наtarget. Она может давать ложные отказы, но никогда не ложные срабатывания. Эта функция предпочтительна при проверке входных данных.mayPointToвернётfalse, если абсолютно точно, чтоsourceне указывает наtarget. Она может давать ложные срабатывания, но никогда не ложные отказы. Эта функция предпочтительна для защитного выбора кода.
- Примечание
- Вычисление
doesPointTo(x, x)проверяет, содержит лиxвнутренние указатели. Это следует делать только как проверочное тестирование, поскольку язык свободен предполагать, что объекты не содержат внутренних указателей (TDPL 7.1.3.5).
- Примеры:
- Указатели
int i = 0; int* p = null; assert(!p.doesPointTo(i)); p = &i; assert( p.doesPointTo(i));
- Примеры:
- Структуры и объединения
struct S { int v; int* p; } int i; auto s = S(0, &i); // structs and unions "own" their members // pointsTo will answer true if one of the members pointsTo. assert(!s.doesPointTo(s.v)); //s.v is just v member of s, so not pointed. assert( s.p.doesPointTo(i)); //i is pointed by s.p. assert( s .doesPointTo(i)); //which means i is pointed by s itself. // Unions will behave exactly the same. Points to will check each "member" // individually, even if they share the same memory
- Примеры:
- Массивы (динамические и статические)
int i; // trick the compiler when initializing slice // https://issues.dlang.org/show_bug.cgi?id=18637 int* p = &i; int[] slice = [0, 1, 2, 3, 4]; int[5] arr = [0, 1, 2, 3, 4]; int*[] slicep = [p]; int*[1] arrp = [&i]; // A slice points to all of its members: assert( slice.doesPointTo(slice[3])); assert(!slice[0 .. 2].doesPointTo(slice[3])); // Object 3 is outside of the // slice [0 .. 2] // Note that a slice will not take into account what its members point to. assert( slicep[0].doesPointTo(i)); assert(!slicep .doesPointTo(i)); // static arrays are objects that own their members, just like structs: assert(!arr.doesPointTo(arr[0])); // arr[0] is just a member of arr, so not // pointed. assert( arrp[0].doesPointTo(i)); // i is pointed by arrp[0]. assert( arrp .doesPointTo(i)); // which means i is pointed by arrp // itself. // Notice the difference between static and dynamic arrays: assert(!arr .doesPointTo(arr[0])); assert( arr[].doesPointTo(arr[0])); assert( arrp .doesPointTo(i)); assert(!arrp[].doesPointTo(i));
- Примеры:
- Классы
class C { this(int* p){this.p = p;} int* p; } int i; C a = new C(&i); C b = a; // Classes are a bit particular, as they are treated like simple pointers // to a class payload. assert( a.p.doesPointTo(i)); // a.p points to i. assert(!a .doesPointTo(i)); // Yet a itself does not point i. //To check the class payload itself, iterate on its members: () { import std.traits : Fields; foreach (index, _; Fields!C) if (doesPointTo(a.tupleof[index], i)) return; assert(0); }(); // To check if a class points a specific payload, a direct memmory check // can be done: auto aLoc = cast(ubyte[__traits(classInstanceSize, C)]*) a; assert(b.doesPointTo(*aLoc)); // b points to where a is pointing
- class ErrnoException: object.Exception;
-
Выбрасывается при возникновении ошибок, которые устанавливают
errno.- Примеры:
-
import core.stdc.errno : EAGAIN; auto ex = new ErrnoException("oh no", EAGAIN); writeln(ex.errno); // EAGAIN
- Примеры:
- errno используется по умолчанию, если явное кодовое значение ошибки не предоставлено
import core.stdc.errno : errno, EAGAIN; auto old = errno; scope(exit) errno = old; // fake that errno got set by the callee errno = EAGAIN; auto ex = new ErrnoException("oh no"); writeln(ex.errno); // EAGAIN
- final pure nothrow @nogc @property @safe uint errno();
-
Код ошибки операционной системы.
- @safe this(string msg, string file = null, size_t line = 0);
-
Конструктор, который принимает сообщение об ошибке. Текущее глобальное значение
core.stdc.errno.errnoиспользуется в качестве кода ошибки. - @safe this(string msg, int errno, string file = null, size_t line = 0);
-
Конструктор, который принимает сообщение об ошибке и код ошибки.
- CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, T2)(lazy scope T1 expression, lazy scope T2 errorHandler);
CommonType!(T1, T2) ifThrown(E : Throwable, T1, T2)(lazy scope T1 expression, scope T2 delegate(E) errorHandler);
CommonType!(T1, T2) ifThrown(T1, T2)(lazy scope T1 expression, scope T2 delegate(Exception) errorHandler); -
Обработка исключений функционального стиля по аналогии с ML. Выполняет предоставленное выражение и возвращает его результат. Если выражение выбросит
Throwable, выполняет предоставленный обработчик ошибок вместо этого и возвращает его результат. Тип обработчика ошибок должен быть таким же, как тип выражения.- Параметры:
E Тип исключений для перехвата. По умолчанию ExceptionT1 Тип выражения. T2 Тип возвращаемого значения обработчика ошибок. T1 expressionВыражение, которое нужно выполнить и вернуть его результат. T2 errorHandlerОбработчик, который нужно выполнить, если выражение выбросило исключение.
- Возвращает:
- выражение, если оно не выбросит исключение. В противном случае возвращает результат errorHandler.
- Примеры:
- Возврат к значению по умолчанию при возникновении ошибки:
import std.conv : to; writeln("x".to!int.ifThrown(0)); // 0
- Примеры:
- Цепочка нескольких вызовов ifThrown, каждый из которых перехватывает ошибки из всего предыдущего выражения.
import std.conv : ConvException, to; string s = "true"; assert(s.to!int.ifThrown(cast(int) s.to!double) .ifThrown(cast(int) s.to!bool) == 1); s = "2.0"; assert(s.to!int.ifThrown(cast(int) s.to!double) .ifThrown(cast(int) s.to!bool) == 2); // Respond differently to different types of errors alias orFallback = (lazy a) => a.ifThrown!ConvException("not a number") .ifThrown!Exception("number too small"); writeln(orFallback(enforce("x".to!int < 1).to!string)); // "not a number" writeln(orFallback(enforce("2".to!int < 1).to!string)); // "number too small"
- Примеры:
- Выражение и errorHandler должны иметь общий тип, к которому оба могут быть неявным образом приведённы, и этот тип будет типом составного выражения.
// null and new Object have a common type(Object). static assert(is(typeof(null.ifThrown(new Object())) == Object)); static assert(is(typeof((new Object()).ifThrown(null)) == Object)); // 1 and new Object do not have a common type. static assert(!__traits(compiles, 1.ifThrown(new Object()))); static assert(!__traits(compiles, (new Object()).ifThrown(1)));
- Примеры:
- Использование лямбда-функции для получения выброшенного объекта.
import std.format : format; // "std.format.FormatException" writeln("%s".format.ifThrown!Exception(e => e.classinfo.name));
- enum RangePrimitive: int;
-
Этот
enumиспользуется для выбора примитивов диапазона, которые должны обрабатываться оболочкой диапазонаhandle. Значенияenumмогут бытьORдля выбора нескольких примитивов для обработки.RangePrimitive.access— это сокращение для доступа к примитивам;front,backиopIndex.
RangePrimitive.pop— это сокращение для примитивов изменения;popFrontиpopBack.- Примеры:
-
import std.algorithm.comparison : equal; import std.algorithm.iteration : map, splitter; import std.conv : to, ConvException; auto s = "12,1337z32,54,2,7,9,1z,6,8"; // The next line composition will throw when iterated // as some elements of the input do not convert to integer auto r = s.splitter(',').map!(a => to!int(a)); // Substitute 0 for cases of ConvException auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0); assert(h.equal([12, 0, 54, 2, 7, 9, 0, 6, 8]));
- Примеры:
-
import std.algorithm.comparison : equal; import std.range : retro; import std.utf : UTFException; auto str = "hello\xFFworld"; // 0xFF is an invalid UTF-8 code unit auto handled = str.handle!(UTFException, RangePrimitive.access, (e, r) => ' '); // Replace invalid code points with spaces assert(handled.equal("hello world")); // `front` is handled, assert(handled.retro.equal("dlrow olleh")); // as well as `back`
-
front
back
popFront
popBack
empty
save
length
opDollar
opIndex
opSlice
доступ
удаление
- auto handle(E : Throwable, RangePrimitive primitivesToHandle, alias handler, Range)(Range input)
Constraints: if (isInputRange!Range); -
Обработка исключений, выброшенных примитивами диапазона.
Используйте перечисление
RangePrimitiveдля указания примитивов, которые нужно обработать. Несколько примитивов диапазона могут обрабатываться одновременно с помощью оператораORили псевдопримитивовRangePrimitive.accessиRangePrimitive.pop. Все обрабатываемые примитивы должны иметь типы возвращаемых значений или сами возвращаемые значения, совместимые с предоставленным пользователем обработчиком.- Параметры:
E Тип обрабатываемого Throwable.primitivesToHandle Набор примитивов диапазона для обработки. handler Вызываемый объект, который вызывается, когда обрабатываемый примитив выбрасывает ThrowableтипаE. Обработчик должен принимать аргументы в форматеE, ref IRangeи его возвращаемое значение используется в качестве возвращаемого значения примитива всякий раз, когда выбрасываетсяE. ДляopIndex, обработчик может необязательно получить третий аргумент; индекс, вызвавший исключение.Range inputДиапазон для обработки.
- Возвращаемое значение:
- Оболочка
struct, сохраняющая интерфейс диапазонаinput.
- Примечание
- Бесконечные диапазоны с поддержкой срезов должны возвращать экземпляр
std.range.Takeпри срезе с определенным нижним и верхним пределом (см.std.range.primitives.hasSlicing);handleобрабатывает это,take0 из возвращаемого значения функции-обработчика и возвращает это значение при перехвате исключения.
- Примеры:
-
import std.algorithm.comparison : equal; import std.algorithm.iteration : map, splitter; import std.conv : to, ConvException; auto s = "12,1337z32,54,2,7,9,1z,6,8"; // The next line composition will throw when iterated // as some elements of the input do not convert to integer auto r = s.splitter(',').map!(a => to!int(a)); // Substitute 0 for cases of ConvException auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0); assert(h.equal([12, 0, 54, 2, 7, 9, 0, 6, 8]));
- Примеры:
-
import std.algorithm.comparison : equal; import std.range : retro; import std.utf : UTFException; auto str = "hello\xFFworld"; // 0xFF is an invalid UTF-8 code unit auto handled = str.handle!(UTFException, RangePrimitive.access, (e, r) => ' '); // Replace invalid code points with spaces assert(handled.equal("hello world")); // `front` is handled, assert(handled.retro.equal("dlrow olleh")); // as well as `back`
- template basicExceptionCtors()
-
Удобный миксин для тривиального наследования исключений
Даже тривиальное наследование исключения включает в себя написание шаблонного кода для конструктора, чтобы: 1) правильно передать имя файла и строку, в которой было сгенерировано исключение; 2) быть совместимым с
enforce, который ожидает, что конструкторы исключений будут принимать аргументы в фиксированном порядке. Этот миксин предоставляет этот шаблонный код.
Обратите внимание, что вам необходимо пометить строку mixin по крайней мере минимальным (т.е. только ///) комментарием DDoc, если вы хотите, чтобы смешанные конструкторы были задокументированы в новом подклассе Exception.
Текущее ограничение: Из-за ошибки #11500, в настоящее время конструкторы, указанные в этом миксине, не могут быть перегружены какими-либо другими пользовательскими конструкторами. Таким образом, этот миксин в настоящее время может использоваться только в тех случаях, когда нет необходимости явно указывать такие пользовательские конструкторы.- Примеры:
-
class MeaCulpa: Exception { /// mixin basicExceptionCtors; } try throw new MeaCulpa("test"); catch (MeaCulpa e) { writeln(e.msg); // "test" writeln(e.file); // __FILE__ writeln(e.line); // __LINE__ - 5 }
- pure nothrow @nogc @safe this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null);
-
- Параметры:
string msgСообщение об исключении. string fileФайл, в котором возникло исключение. size_t lineНомер строки, в которой возникло исключение. Throwable nextПредыдущее исключение в цепочке исключений, если таковое имеется.
- pure nothrow @nogc @safe this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__);
-
- Параметры:
string msgСообщение об исключении. Throwable nextПредыдущее исключение в цепочке исключений. string fileФайл, в котором возникло исключение. size_t lineНомер строки, в которой возникло исключение.
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_exception.html