我知道是什么yield,我看过几个例子,但我想不到现实生活中的应用,你用它来解决一些具体问题吗?
(理想情况下,某些其他问题无法解决的问题)
通过一个教程(Professional ASP.NET MVC - Nerd Dinner),我遇到了这段代码:
public IEnumerable<RuleViolation> GetRuleViolations() {
if (String.IsNullOrEmpty(Title))
yield return new RuleViolation("Title required", "Title");
if (String.IsNullOrEmpty(Description))
yield return new RuleViolation("Description required","Description");
if (String.IsNullOrEmpty(HostedBy))
yield return new RuleViolation("HostedBy required", "HostedBy");
if (String.IsNullOrEmpty(Address))
yield return new RuleViolation("Address required", "Address");
if (String.IsNullOrEmpty(Country))
yield return new RuleViolation("Country required", "Country");
if (String.IsNullOrEmpty(ContactPhone))
yield return new RuleViolation("Phone# required", "ContactPhone");
if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
yield return new RuleViolation("Phone# does not match country", "ContactPhone");
yield break;
}
Run Code Online (Sandbox Code Playgroud)
我已经读过了yield,但我想我的理解仍然有点朦胧.它似乎做的是创建一个对象,允许循环遍历集合中的项目而不实际进行循环,除非并且直到它是绝对必要的.
不过,这个例子对我来说有点奇怪.我认为它正在做的是延迟任何 …
我有一个for循环来检查一系列条件.在每次迭代时,它应仅为其中一个条件产生输出.如果没有条件为真,则最终产量是默认值.在每块收益率之后我是否必须继续?
def function():
for ii in aa:
if condition1(ii):
yield something1
yield something2
yield something3
continue
if condition2(ii):
yield something4
continue
#default
yield something5
continue
Run Code Online (Sandbox Code Playgroud) 我得到了这个方法(在Unity C#Script中),但我不明白"yield"部分是如何工作的.
我从MSDN知道该函数将返回一个我可以迭代的IEnumerator,但是这段代码等待了1.5秒并且没有迭代,因为这意味着,内部创建的对象被多次创建.这里的任何人都可以解释一下这段代码的工作原理
IEnumerator DestroyShip()
{
// create new gameobject
Instantiate(ExplosionPrefab, transform.position, transform.rotation);
// make current gameobject invisible
gameObject.renderer.enabled = false;
// set new position for the current gameobject
transform.position = new Vector3(0f, transform.position.y, transform.position.z);
// wait for 1,5 seconds
yield return new WaitForSeconds(1.5f);
// make the current gameobject visible again
gameObject.renderer.enabled = true;
}
Run Code Online (Sandbox Code Playgroud) 以下是将可迭代项目拆分为子列表的两个函数.我相信这种类型的任务是多次编程的.我使用它们来解析由repr('result','case',123,4.56)和('dump',..)等行组成的日志文件.
我想改变这些,以便它们将产生迭代器而不是列表.因为列表可能会变得非常大,但我可以根据前几个项目决定接受或跳过它.此外,如果iter版本可用,我想嵌套它们,但这些列表版本会通过复制部分浪费一些内存.
但是从可迭代源中获取多个生成器对我来说并不容易,所以我请求帮助.如果可能的话,我希望避免引入新课程.
另外,如果您对这个问题有更好的标题,请告诉我.
谢谢!
def cleave_by_mark (stream, key_fn, end_with_mark=False):
'''[f f t][t][f f] (true) [f f][t][t f f](false)'''
buf = []
for item in stream:
if key_fn(item):
if end_with_mark: buf.append(item)
if buf: yield buf
buf = []
if end_with_mark: continue
buf.append(item)
if buf: yield buf
def cleave_by_change (stream, key_fn):
'''[1 1 1][2 2][3][2 2 2 2]'''
prev = None
buf = []
for item in stream:
iden = key_fn(item)
if prev is None: prev = iden
if …Run Code Online (Sandbox Code Playgroud) 我希望有一种更好的方法来编写这种方法和重载,减少代码重复.我想在列表中的项之间返回一系列增量.这种方法: -
public static IEnumerable<decimal> CalculateDeltas(this IEnumerable<decimal> sequence)
{
decimal prev = default(decimal);
foreach (var item in sequence)
{
var current = item;
decimal diff = current - prev;
prev = item;
yield return diff;
}
}
Run Code Online (Sandbox Code Playgroud)
工作得很好.
然后我考虑了一个允许绝对增量的重载,但如果不需要绝对值,则会调用原始方法: -
public static IEnumerable<decimal> CalculateDeltas(this IEnumerable<decimal> sequence,bool absolute)
{
if (absolute)
{
decimal prev = default(decimal);
foreach (var item in sequence)
{
var current = item;
decimal diff = Math.Abs(current - prev);
prev = item;
yield return diff;
}
}
else …Run Code Online (Sandbox Code Playgroud) import contextlib
import time
@contextlib.contextmanager
def time_print(task_name):
t = time.time()
try:
yield
finally:
print task_name, "took", time.time() - t, "seconds."
def doproc():
x=1+1
with time_print("processes"):
[doproc() for _ in range(500)]
# processes took 15.236166954 seconds.
Run Code Online (Sandbox Code Playgroud)
什么时候doproc在使用这个装饰器时被执行?
我正在学习F#,但我很难理解这一点:
let allPrimes =
let rec allPrimes' n =
seq {
if isPrime n then
yield n
yield! allPrimes' (n + 1) }
allPrimes' 2
Run Code Online (Sandbox Code Playgroud)
yield!即使我读过其他更简单的例子,我也无法弄清楚算子究竟做了什么,它似乎yield!返回了一个内部序列.
我有这个递归发生器
var obj = [1,2,3,[4,5,[6,7,8],9],10]
function *flat(x) {
if (Array.isArray(x))
for (let y of x)
yield *flat(y)
else
yield 'foo' + x;
}
console.log([...flat(obj)])Run Code Online (Sandbox Code Playgroud)
它工作正常,但我不喜欢这for部分.有没有办法在功能上写它?我试过了
if (Array.isArray(x))
yield *x.map(flat)
Run Code Online (Sandbox Code Playgroud)
这没用.
有没有办法在没有for循环的情况下编写上述函数?
之间的区别return,并yield似乎很清楚,直到我想通了,也有yield from和可能性都结合起来return,并yield以非常相似的功能!
我的理解return是之后的一切都没有执行,对吧?
然而:
function generate(): iterable {
return [1, 2, 3];
}
foreach (generate() as $value) {
echo $value;
}
Run Code Online (Sandbox Code Playgroud)
产生:“123”
但以下内容:
function generate(): iterable {
return [1, 2, 3];
yield;
}
foreach (generate() as $value) {
echo $value;
}
Run Code Online (Sandbox Code Playgroud)
什么都不生产!所以这意味着yield被执行了?
这是一个错误吗?
yield ×10
generator ×5
c# ×4
python ×3
ienumerable ×2
.net ×1
ecmascript-6 ×1
f# ×1
iterator ×1
javascript ×1
php ×1
refactoring ×1
return ×1
yield-return ×1