Здравствуйте, VladD2, Вы писали:
FR>>Это да, но в D в отличии от C++ можно без проблем писать полностью типобезопасно. Ключик компилятора который превращал бы в ошибки использование опасного кода не помешал бы.
VD>У D такой есть? Нет? Тогда в чем разница с С++?
Ну, после нескольких дней штудирования документации по D набрался не такой уж и маленький список отличий D от C++. Вот, например, перечень того, что лично мне нравится в D по сравнению с C++:
* Фиксированные и не зависящие от платформы размерности примитивных типов (т.к. byte, short, int, long, ...).
* Наличие properties у объектов и типов (т.к. .init, .min, .max, .sizeof, .alignof и пр):
int a;
int b = 1;
typedef int t = 2;
t c;
t d = cast(t)3;
int.init // is 0
a.init // is 0
b.init // is 1
t.init // is 2
c.init // is 2
d.init // is 3
struct Foo
{
int a;
int b = 7;
}
Foo.a.init // is 0
Foo.b.init // is 7
* Все переменные и члены классов инициализируются значениями по умолчанию.
* Объявление локальной переменной без инициализации является ошибкой.
* Автоматический вывод типов через auto и в операторе foreach.
* Унифицированный способ приведения типов через cast (в отличии от зоопарка приведений типов в C++).
* Наличие строгого typedef (порождает подтипы) и alias (псевдоним для существующего типа).
* Наличие свойства length у массивов и операции слайсинга массивов.
* Порождение исключения в switch, если на сработал ни один из case. (Если не ошибаюсь, ты приводил этот пример как доказательство большой безопасности Nemerle по сравнению с Java.)
* Возможность использования в case строковых литералов.
char[] name;
...
switch (name)
{
case "fred":
case "sally":
...
}
* Статические конструкторы и статические деструкторы классов и модулей. Про счетчики Шварца теперь можно забыть.
* Инварианты класса:
class Range
{
this( int left, int right )
{
_left = left;
_right = right;
}
invariant
{
assert( _left <= _right, "_left must be less or equal to _right" );
}
...
}
* Встроенные в язык unit-тесты.
class Range
{
...
int opApply( int delegate( inout int ) dg )
{
int r = 0;
for( int i = _left; i != _right; ++i )
{
r = dg( i );
if( r )
break;
}
return r;
}
unittest
{
int cycles = 0;
foreach( i; new Range( 0, 4 ) )
{
++cycles;
}
assert( 4 == cycles );
}
...
}
* Наличие static assert.
* Стандартный единый базовый класс Error для всех исключений. И нет сотен мегатон унаследованного кода, в котором исключения порождались как попало и с любыми типами.
* scope-конструкции, которые упрощают написание exception safe кода:
int doSomethingImportant()
{
// Здесь делаем что-то, что при порождении исключения нужно откатить.
...
// Реакция на исключение.
scope(failure) doRollback();
... // Продолжение работы.
}
* Вложенные функции, классы, структуры.
* Нет макросов, каждый символ означает в точности то, что он означает.
* Типобезопасные функции с переменным числом аргументов.
* Параметрами шаблонов могут быть строки и вещественные значения.
* Параметрам шаблонов можно назначать специализации:
template TBar( D, U:D[] ) {}
template TFoo( T: T* ) {}
Имхо, достойный список того, что уже есть в языке сейчас. Даже по сравнении с тем, что может появится в стандарте C++ через пару лет, а затем, еще через пару лет, в компиляторах.