В современных языках программирования стало модно использовать автоматический вывод типов (type inference). Веяние сие даже до C++ добралось – в C++0x ключевое слово auto при декларации переменной будет означать автоматический вывод типа:
auto result = std::shared_ptr< MyType >( new MyType() );
Очень неоднозначно я к этой штуке отношусь. Был у меня опыт изучения чужих исходников на D и Scala, где эти фичи использовались в полный рос – мрак. Документации приходится перелопачивать гораздо больше, чем в случае с аннотациями типов. Особенно в случаях, когда переменной присваивается неизвестно что:
auto writer = getDevice().getConduit();
Что за Device возвращается, что потом за Conduit оказывается во writer-е – без поллитры не разберешься.
А вот свежий пример: потребовалось мне в старом исходнике обнаружить места использования некоторой структуры. Нет проблем – контекстным поиском по файлу все эти места обнаруживаются на раз. В простом FAR-овском просмоторщике файлов. А если бы я использовал вывод типов? Да застрелиться бы можно было бы, если бы под рукой не было мощной IDE, в которой должна была бы быть возможность найти все использования конкретного типа.
Так что, наверное, где-то вывод типов хорош (скажем, чтобы принять результат boost::bind или анонимный тип в LINQ). Но чем меньше, тем лучше. Имхо, конечно.
5 комментариев:
auto writer = getDevice().getConduit(); Что за Device возвращается, что потом за Conduit оказывается во writer-е – без поллитры не разберешься.
Ок, берем плюсы: чем отличается использование typedef'ов всяких составных типов, чьи объявления равномерно разбросаны по коду?
Скажем, какой-нибудь IndirectWorker w = GlobalFactory.get().CreateIndWorker();
Или автор кода должен писать читабельно для посторонних в ущерб удобству собственной работы?
В плюсах IndirectWorker можно найти в проекте контекстным поиском. А в D приходится сначала искать тип возвращаемого значения метода getDevice(), затем смотреть, что возвращает getConduit(). Телодвижений больше оказывается.
>Или автор кода должен писать читабельно для посторонних в ущерб удобству собственной работы?
Именно так. Простота чтения кода важнее простоты его написания.
К сожалению, в C-подобных языках изначально разработчик обречен на дублирование имен. Но, например, в Eiffel или в Zimbu ситуация совсем другая. Там и декларации типов делаются, и писать нужно не много.
В плюсах IndirectWorker можно найти в проекте контекстным поиском.
Найти и обнаружить, что это - класс, созданный с прицелом под реализацию в наследниках, после чего искать, что же это за фабрика и что она на самом деле creates.
Это, конечно, утрированно, смысл вот в чем: ди не обязывает пользоваться auto; видимо, автор кода считал это уместным, а это уже вопрос к автору, не к языку - и на плюсах можно навести туману.
Примеров, уверен, вы и сами можете пару страниц привести.
Именно так. Простота чтения кода важнее простоты его написания.
Что там было про "вот, бл*" при написании очередной обязаловки, диктуемой яп?
scope cont = GetSomeCont;
foreach(ind, val; cont) {}
Вот это - быстно и удобно, и ежели работа идет не в команде с четким style guide (или любыми другими договоренностями), все посторонние идут лесом.
>Найти и обнаружить, что это - класс, созданный с прицелом под реализацию в наследниках, после чего искать, что же это за фабрика и что она на самом деле creates.
Вы говорите не о том. Есть выражение:
auto w = getDevice().getConduit();
Какой тип у w? Какие методы у объекта w можно вызывать? Без документации на getDevice и на возвращаемый им тип (в худшем случае еще и на какой-то из его наследников) это не определить.
Если же записано:
MyDeviceConduit w = getDevice().getConduit();
то все понятно сразу.
Более того, компилятор будет мне давать по рукам, если MyDeviceConduit не совместим с возвращаемым getConduit типом. В месте обращения к getConduit().
>Вот это - быстно и удобно, и ежели работа идет не в команде с четким style guide (или любыми другими договоренностями), все посторонние идут лесом.
Забота о команде -- это, конечно, хорошо. Но думать нужно и о себе так же. А для себя свой собственный код даже полугодовалой давности будет восприниматься как совершенно чужой. Так что, если даже собственное удобство не интересно, то программу можно превратить к криптограмму, нет проблем.
Вывод типов в ряде случаев имеет смысл. Скажем, в шаблонном коде:
template< class T > void put_data( T & terminal ) {
auto conduit = terminal.getDevice().getConduit();
conduit.write( data_header );
conduit.flush();
}
Только есть у меня сомнения, что вывод типов будут применять настолько избирательно.
Отправить комментарий