- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我创建了一个small macro metaprogramming library,它实现了基本有用的构造,例如REPEAT(times, x)
,IF(value, true, false)
,元组等。
我的大多数实现都是通过根据可变参数的数量或通过计数器重载宏来工作的:
// Example:
#define REPEAT_0(x)
#define REPEAT_1(x) x REPEAT_0(x)
#define REPEAT_2(x) x REPEAT_1(x)
#define REPEAT_3(x) x REPEAT_2(x)
// ...
// (these defines are generated using an external script)
// ...
#define REPEAT(count, x) CAT(REPEAT_, count)(x)
DEFER
和
OBSTRUCT
的使用方面遇到了很多麻烦。
REPEAT
版本,不需要脚本生成的定义,如下所示:
#define EAT(...)
#define EXPAND(...) __VA_ARGS__
#define WHEN(c) IF(c)(EXPAND, EAT)
#define REPEAT(count, macro, ...) \
WHEN(count) \
( \
OBSTRUCT(REPEAT_INDIRECT) () \
( \
DEC(count), macro, __VA_ARGS__ \
) \
OBSTRUCT(macro) \
( \
DEC(count), __VA_ARGS__ \
) \
)
#define REPEAT_INDIRECT() REPEAT
//An example of using this macro
#define M(i, _) i
EVAL(REPEAT(8, M, ~)) // 0 1 2 3 4 5 6 7
DEFER
,
OBSTRUCT
和其他实用程序的实现方式如下:
#define EMPTY()
#define DEFER(id) id EMPTY()
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
#define EXPAND(...) __VA_ARGS__
#define A() 123
A() // Expands to 123
DEFER(A)() // Expands to A () because it requires one more scan to fully expand
EXPAND(DEFER(A)()) // Expands to 123, because the EXPAND macro forces another scan
EXPAND(...)
宏是否强制进行附加扫描? 如果是,此扫描是否允许宏递归扩展? EXPAND(...)
和DEFER(id)
有什么区别? DEFER
是否强制执行两次附加扫描? OBSTRUCT(...)
宏呢?是否会强制进行两次其他扫描? OBSTRUCT
的递归实现中需要REPEAT
?为什么DEFER
或EXPAND
在这里不起作用? 最佳答案
通常使用诸如DEFER
之类的宏以及复杂的C宏,取决于对C预处理器实际上是如何扩展宏表达式的理解。它不仅试图像传统编程语言一样减少所有的表达式树,而且还可以在线性 token 流上工作,并且在当前正在检查流中是否有可能替换的地方具有隐式“cursor”。在扩展过程的任何给定“堆栈帧”内,光标永远不会向后移动,并且一旦 token 已在流中传递,就不会再次检查它。
逐步了解DEFER
的操作的第一个示例:
DEFER(A)() // cursor starts at the head of the sequence
^ // identifies call to DEFER - push current position
DEFER( A )() // attempt to expand the argument (nothing to do)
^
// replace occurrences of id in DEFER with A,
// then replace the call to it with the substituted body
A EMPTY() () // pop cursor position (start of pasted subsequence)
^ // doesn't find an expansion for A, move on
A EMPTY() () // move to next token
^ // EMPTY() is a valid expansion
A () // replace EMPTY() with its body in the same way
^ // continuing...
A () // `(` is not a macro, move on
^
A ( ) // `)` is not a macro, move on
^
A () // end of sequence, no more expansions
^
A
主体的“重新扫描”期间,光标移过
DEFER
,这是扩展该组 token 的第二次也是最后一次尝试。一旦光标移过
A
,它就不会在该扩展序列中返回它,并且由于“重新扫描”在顶层,因此没有后续的扩展序列。
EXPAND
的调用中:
EXPAND(DEFER(A)()) // cursor starts at the head etc.
^ // identifies call to EXPAND
EXPAND( DEFER(A)() ) // attempt to expand the argument
^ // this does the same as the first
// example, in a NESTED CONTEXT
// replace occurrences of __VA_ARGS__ in EXPAND with A ()
// then replace the call with the substituted body
A () // pop cursor position (start of pasted subsequence)
^ // identifies A, and can expand it this time
EXPAND
-通过扩展光标在流中的位置,为扩展游标提供了一个“免费”的额外游程,以进行额外的重新扫描遍历,从而获得了额外的时间,因此为每个新构造的调用表达式(即,将宏名和带括号的参数列表)被扩展器识别的额外机会。因此,
EVAL
所做的只是为您提供363次免费重新扫描通行证(3 ^ 5 + 3 ^ 4 + 3 ^ 3 + 3 ^ 2 + 3,有人检查了我的数学运算)。
DEFER
的要点是确保不会在宏的扩展过程中生成递归调用,而是推迟执行...直到外部重新扫描步骤为止,此时该步骤不会被涂成蓝色,因为我们不再位于该命名宏内。这就是REPEAT_INDIRECT
类似于函数的原因;只要我们仍然在REPEAT
的主体内,就可以防止它扩展到提及REPEAT
名称的任何内容。原始REPEAT
完成后,至少需要再进行一次免费通行证才能扩展EMPTY
token 间隔。 EXPAND
强制执行附加扩展。任何宏调用都会向其参数列表中传递的任何表达式授予一次额外的扩展传递。DEFER
的思想是,您不将其传递为整个表达式,而只是传递“功能”部分。它将在函数与其参数列表之间插入一个间隔,该间隔需要花费一次扩展才能删除。 EXPAND
和DEFER
之间的区别在于DEFER
要求在传递的函数扩展之前需要额外的传递;而EXPAND
提供了额外的通行证。因此它们彼此相反(如第一个示例所示,它们一起应用,等效于不使用二者的调用)。 OBSTRUCT
在通过传递的函数之前需要花费两次扩展传递。它通过DEFER
将EMPTY()
分隔符扩展一个(EMPTY EMPTY() ()
),并在摆脱嵌套的EMPTY
时刻录第一个光标重置来实现此目的。 OBSTRUCT
周围需要
REPEAT_INDIRECT
,因为WHEN
扩展(按真)可以调用EXPAND
,这将在我们仍在REPEAT
调用中的同时消除一层间接。如果只有一层(DEFER
),则当我们仍在REPEAT
的上下文中时,将生成嵌套的REPEAT
,从而将其涂成蓝色,并终止此处的递归。在OBSTRUCT
中使用两层意味着在到达REPEAT
之外的任何宏调用的重新扫描过程之前,不会生成嵌套的REPEAT
,这时我们可以安全地再次生成名称,而无需将其涂成蓝色,因为它是从无扩展堆栈。 EVAL
)起作用,并通过至少一个重新扫描遍历延迟其内部宏名称的扩展,以便在调用堆栈的更远处进行。
REPEAT
主体的第一个扩展发生在
EVAL[363]
的重新扫描期间,递归调用被推迟到
EVAL[362]
的重新扫描,嵌套扩展被推迟...等等。这不是真正的递归,因为它不能形成无限循环,而是依靠外部堆栈帧来进行烧录。
关于c++ - 了解DEFER和OBSTRUCT宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29962560/
在 javascript 中使用 defer 属性的正确语法是什么? 我见过有两种方式: 1: ... 2: ... 根据经验 [和我找不到的引用资料],我更倾向于使用第二个选项,但我只是仔细检查了
有什么区别 var dfd = new $.Deferred 和 var dfd = $.Deferred 在哪些情况下需要使用 new 与不使用它? 最佳答案 jQuery official doc
给定使用 Promise 构造函数的代码 let promise = () => new Promise(resolve => resolve(1)); new Promise((resolve, r
我正在研究 RxKotlin,问题出现了:defer() 和 defer{} 有什么区别 最佳答案 defer() 和 defer {} 只是写同一件事的两种方式。 Kotlin 在某些特定情况下允许
我正在尝试使用 Python 在 Google App Engine 上执行此操作: def add_to_db(person): a = PersonDb(key_name = perso
所以我有一个延迟对象数组dataCalls。 目前我正在使用以下方法来解雇所有这些,并在所有 Deferreds 解决后调用回调: $.when.apply(null, dataCalls) .
考虑以下几点: function foo(){ // Returns the jQuery deffered below. var urlToUse; $.ajax({
我刚刚看到此代码已被弃用,我一直在尝试遵循此指南:http://www.codelord.net/2015/09/24/$q-dot-defer-youre-doing-it-wrong/以正确的方式
我有一些元素,其中一些代码依赖于其他 中的代码元素。我看到了defer属性在这里可以派上用场,因为它允许推迟执行代码块。 为了测试它,我在 Chrome 上执行了这个:http://jsfiddle
我需要向 jQuery 的 .when() 监视的函数添加未知数量(仅在运行时已知)的 .pipe() 调用。这些调用将基于另一个异步操作的 ajax 调用。请参阅下面的代码以获得更清晰的解释: $.
我正在使用 GAE 的“deffered” ' 库 (python),它会在出现异常时自动重试任务。 有没有办法知道(在任务处理函数中)任务已尝试的次数? 我的最终目标是实现如下内容: if num_
我有几个 元素,其中一些代码依赖于其他 中的代码元素。我看到了defer属性在这里可以派上用场,因为它允许代码块在执行中被推迟。 为了测试它,我在 Chrome 上执行了这个:http://jsfi
在我看来,两者都做同样的事情。 文档: deferred.always() deferred.then() 最佳答案 看起来deferred.then()允许您传递两个单独的成功和失败回调,而 def
我正在使用 Twisted 编写代码,但在为我的扭曲互联网延迟变量想出一个合理的变量名时遇到了麻烦。这是我的候选人: d :太通用,太短,违反了 pylint 规则 C0103。 def :与内置函数
是否存在这样的情况:调用 .callback() 或 .errback() 会向调用者引发异常,而该异常不会被延迟捕获? 假设我有以下延迟和回调: from twisted.internet impo
这是代码: http://jsbin.com/lizami/edit?js,console 将代码也粘贴到此处: var aaa = $.Deferred(); var bbb = function(
这是我的尝试: deferred.defer(class1().method1, class2.method2, arg) deferred.defer(class1().method1, class
我正在尝试使用 google.appengine.ext.deferred 来运行任务。我正在将一个方法传递给 defer() 方法,该方法成功运行,但在返回时抛出一个 ValueError: F
这个问题在这里已经有了答案: What's the difference between a Deferred object and its own promise object? (3 个答案)
我下载了一个名为 jsdeferred 的库来尝试帮助我解决一些代码流问题,但我有点迷茫,因为它的示例和...“文档” 在某些事情上有点不清楚。但是当我继续阅读和挖掘,当然还有谷歌搜索阳光下的一切时,
我是一名优秀的程序员,十分优秀!