Становится ли поток программы трудным для следовать быстрее, чем если нефункциональный язык используется?
Это может иметь место, в котором функциональный стиль поощряет программиста предпочитать думать с точки зрения абстрактных, логических преобразований, нанося на карту исходные данные к продукции. Мышление с точки зрения «потока программ» предполагает последовательный, учитывающий состояние режим работы - и хотя функциональная программа может иметь последовательное состояние «под колпаком», она обычно не структурирована вокруг этого.
Различие в перспективе можно легко увидеть путем сравнения императивных и функциональных подходов к «обработке сбора данных». Первый имеет тенденцию использовать структурированную итерацию, как для
или во время
цикла, указывая программе «делать эту последовательность задач, затем переходить к следующей и повторять, пока это не будет сделано». Последняя склонна использовать абстрактную рекурсию, как функция fold
или map
, указывая программе, что «вот функция объединения/преобразования элементов - используйте ее». Нет необходимости следовать рекурсивному программному потоку через такую функцию, как map
; потому что это абстракция без гражданства, достаточно думать о том, что она значит, а не о том, что она делает.
Возможно, несколько показательно, что функциональный подход медленно переползает в нефункциональные языки - считают foreach
петли, постижения списка Пайтона...
Вот небольшой код, показывающий, как получить фабрику классов и использовать ее для создания COM-объекта. Он использует структуру, чтобы сохранить трека дескриптора модуля и указателя функции Dll GetClassObject. Вы должны держаться за дескриптор модуля, пока не закончите работу с COM-объектом.
Чтобы использовать эту функцию, необходимо выделить экземпляр структуры ComModureInfo и установить для szDLL имя файла DLL или полное имя пути. Затем вызовите функцию с идентификатором класса и идентификатором интерфейса COM-объекта, который требуется получить из этой DLL.
typedef struct {
TCHAR szDLL[MAX_PATH];
HMODULE hModule;
HRESULT (WINAPI *pfnGetFactory)(REFCLSID, REFIID, void**);
} ComModuleInfo;
HRESULT CreateCOMObject(
ComModuleInfo & mod, // [in,out]
REFCLSID iidClass, // [in] CLSID of the COM object to create
REFIID iidInterface, // [in] GUID of the interface to get
LPVOID FAR* ppIface) // [in] on success, interface to the COM object is returned
{
HRESULT hr = S_OK;
*ppIface = NULL; // in case we fail, make sure we return a null interface.
// init the ComModuleInfo if this is the first time we have seen it.
//
if ( ! mod.pfnGetFactory)
{
if ( ! mod.hModule)
{
mod.hModule = LoadLibrary(mod.szDLL);
if ( ! mod.hModule)
return HRESULT_FROM_WIN32(GetLastError());
}
mod.pfnGetFactory = (HRESULT (WINAPI *)(REFCLSID, REFIID, void**))GetProcAddress(mod.hModule, "DllGetClassObject");
if ( ! mod.pfnGetFactory)
return HRESULT_FROM_WIN32(GetLastError());
}
IClassFactory* pFactory = NULL;
hr = mod.pfnGetFactory(iidClass, IID_IClassFactory, (void**)&pFactory);
if (SUCCEEDED(hr))
{
hr = pFactory->CreateInstance(NULL, iidInterface, (void**)ppIface);
pFactory->Release();
}
return hr;
}
-121--3763393- Руководство по базовому вводу/выводу содержит подробную информацию.
Когда вы получаете данные из потока, он немедленно отправляется и извлекает запрошенные биты и фрагменты непосредственно из источника, аналогично прослушиванию онлайн-радиопередач. Это как сугубо прямая трансляция.
Буфер получает больше, чем просто то, что было запрошено от источника, и сохраняет его в памяти, поэтому не так много запросов на получение более мелких частей (постоянный ввод-вывод или пропускная способность сети). Это похоже на загрузку радиопередачи и последующее ее прослушивание ... пропуск / возврат не вызовет дополнительных вызовов выборки, поскольку все / большая часть данных уже присутствует.