如果我单步执行以下代码,则会跳过对ReturnOne()的调用.
static IEnumerable<int> OneThroughFive()
{
ReturnOne();
yield return 2;
yield return 3;
yield return 4;
yield return 5;
}
static IEnumerator<int> ReturnOne()
{
yield return 1;
}
Run Code Online (Sandbox Code Playgroud)
我只能假设编译器正在剥离它,因为我正在做的是无效的.我希望能够将我的枚举分离成各种方法.这可能吗?
我正在使用一个PHP类,它需要接受多种类型的迭代器并将它们包含在统一的包装器中.我需要支持的一种迭代器(并且可以!)是一个包含yield关键字的匿名函数 - 本质上是一个匿名生成器.
有没有办法在PHP中测试匿名函数是否是生成器?以下是我尝试过的方法列表(旨在显示输出,而不是我如何使用它们):
$anon = function() { yield 1; yield 2; }; // build anonymous generator
gettype($anon); // "object"
$anon instanceof \Traversable; // 0
$anon instanceof \Iterable; // 0
$anon instanceof \IteratorAggregate; // 0
$anon instanceof \Generator; // 0
$anon instanceof \Closure; // 1 -- but doesn't tell me whether or not the closure is actually generator
$anon = $anon(); // invoke, then run the same checks
gettype($anon); // "object"
$anon instanceof \Traversable; // 1 (!!!)
$anon instanceof \Iterable; …Run Code Online (Sandbox Code Playgroud) ES-6 iterator.throw(err)方法通常被描述为注入异常,就好像它发生在yield生成器中的语句中一样.问题是此异常的堆栈跟踪不包含对yield语句的文件/行的任何引用,甚至不包含它所在的函数.相反,堆栈跟踪似乎只在构造异常对象时生成,哪个不在里面generator.
问题是:如何在堆栈跟踪中获取有问题的yield语句的位置?
function* one_of_many_generators() {
// ...
yield ajax(url); // <-- what I need in the stack trace
// ...
}
function outer() {
var iterator = one_of_many_generators();
iterator.next(); // runs to the first yield
// inject exception at the yield statement
iterator.throw(Error("error")); // <-- top of stack trace shows here
}
Run Code Online (Sandbox Code Playgroud)
虽然这个问题不是特定的Promises,但它们可能更容易描述问题.就我而言,我正在使用具有生成器和承诺的任务系统.假设函数ajax()返回Promise,如果拒绝,则使用此机制将错误转换为yield语句中的throw.
调试器中的堆栈跟踪非常无用,因为我找不到获取yield statement此注入发生位置的函数,文件或行号的方法.调用iterator.throw(err)被视为重新抛出,并且不会获得新的堆栈信息,因此它只显示ajax()函数内部可以从许多地方调用的位置,并且通过outer()像上面的示例中那样抛出新错误,相同的抛出线显示对于所有错误.两者都没有给出generator关于调试错误所执行的函数的提示. …
这个代码,包括赋值和yield运算符,如何工作?结果相当混乱.
def test1(x):
for i in x:
_ = yield i
yield _
def test2(x):
for i in x:
_ = yield i
r1 = test1([1,2,3])
r2 = test2([1,2,3])
print list(r1)
print list(r2)
Run Code Online (Sandbox Code Playgroud)
输出:
[1, None, 2, None, 3, None]
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud) [注意:我在Go中阅读了Python风格的生成器,这不是它的重复.]
在Python/Ruby/JavaScript/ECMAScript 6中,可以使用yield语言提供的关键字编写生成器函数.在Go中,可以使用goroutine和channel模拟它.
以下代码显示了如何实现置换函数(abcd,abdc,acbd,acdb,...,dcba):
// $src/lib/lib.go
package lib
// private, starts with lowercase "p"
func permutateWithChannel(channel chan<- []string, strings, prefix []string) {
length := len(strings)
if length == 0 {
// Base case
channel <- prefix
return
}
// Recursive case
newStrings := make([]string, 0, length-1)
for i, s := range strings {
// Remove strings[i] and assign the result to newStringI
// Append strings[i] to newPrefixI
// Call the recursive case
newStringsI …Run Code Online (Sandbox Code Playgroud) 一个例子:
val l = List(1,2,3)
val t = List(-1,-2,-3)
Run Code Online (Sandbox Code Playgroud)
我可以这样做吗?
for (i <- 0 to 10) yield (l(i)) yield (t(i))
Run Code Online (Sandbox Code Playgroud)
基本上我想为每次迭代产生多个结果.
我有一个Python生成器,可以调用自己来获得更多元素.它看起来像这样:
def gen(list):
# ...
if list:
for x in gen(list[1:]):
yield x
Run Code Online (Sandbox Code Playgroud)
我的问题是关于最后两行:是否有更简洁的方式来表达这一点?我希望有这样的东西(理解这不是有效的Python原样):
def gen(list):
# ...
if list:
yield each in gen(list[1:])
Run Code Online (Sandbox Code Playgroud) 当我在for循环中使用生成器时,它似乎"知道",当没有更多元素产生时.现在,我必须使用没有for循环的生成器,并手动使用next()来获取下一个元素.我的问题是,我怎么知道,如果没有更多的元素?
我只知道:next()引发一个异常(StopIteration),如果没有剩下的东西,那么对于这样一个简单的问题来说,这不是一个例外吗?是不是像has_next()那样的方法?
以下几行应该说清楚,我的意思是:
#!/usr/bin/python3
# define a list of some objects
bar = ['abc', 123, None, True, 456.789]
# our primitive generator
def foo(bar):
for b in bar:
yield b
# iterate, using the generator above
print('--- TEST A (for loop) ---')
for baz in foo(bar):
print(baz)
print()
# assign a new iterator to a variable
foobar = foo(bar)
print('--- TEST B (try-except) ---')
while True:
try:
print(foobar.__next__())
except StopIteration:
break
print()
# assign …Run Code Online (Sandbox Code Playgroud) 因为回调中不允许"yield" - 语句,我如何在回调中使用redux-saga的"put"功能?
我想要进行以下回调:
function onDownloadFileProgress(progress) {
yield put({type: ACTIONS.S_PROGRESS, progress})
}
Run Code Online (Sandbox Code Playgroud)
这不起作用并以"意外令牌"结束,因为普通函数不允许产生.否则我不能将回调作为" 函数* " 传递,这将允许收益.ES6似乎在这里打破了.
我读过redux-saga提供了一些称为" 频道 "的功能,但说实话,我没有得到它.我已经多次阅读过关于这些频道和示例代码的内容,但在所有示例中,他们都解决了非常困难和不同的问题,而不是我的简单案例,并且在一天结束时我已经到了那里.
有人能告诉我如何处理这个问题的解决方案吗?
整个背景:
function onDownloadFileProgress(progress) {
yield put({type: ACTIONS.S_PROGRESS, progress})
}
export function * loadFile(id) {
let url = `media/files/${id}`;
const tempFilename = RNFS.CachesDirectoryPath + '/' + id;
const download = RNFS.downloadFile( {
fromUrl: url,
toFile: tempFilename,
background: false,
progressDivider: 10,
progress: onDownloadFileProgress,
})
yield download.promise;
}
Run Code Online (Sandbox Code Playgroud) 假设我有这个 python 代码:
def double_inputs():
while True:
x = yield
yield x * 2
gen = double_inputs()
next(gen)
print(gen.send(1))
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,它打印“2”。我可以像这样在 c++20 中制作一个生成器:
#include <coroutine>
template <class T>
struct generator {
struct promise_type;
using coro_handle = std::coroutine_handle<promise_type>;
struct promise_type {
T current_value;
auto get_return_object() { return generator{coro_handle::from_promise(*this)}; }
auto initial_suspend() { return std::suspend_always{}; }
auto final_suspend() { return std::suspend_always{}; }
void unhandled_exception() { std::terminate(); }
auto yield_value(T value) {
current_value = value;
return std::suspend_always{};
}
};
bool next() { return coro …Run Code Online (Sandbox Code Playgroud) yield ×10
generator ×5
python ×3
ecmascript-6 ×2
javascript ×2
recursion ×2
ajax ×1
c# ×1
c++ ×1
c++20 ×1
closures ×1
go ×1
ienumerable ×1
iteration ×1
next ×1
php ×1
python-3.x ×1
redux ×1
redux-saga ×1
scala ×1