我有一个很大的结构,我知道从剖析,是昂贵的复制。我正在使用in
关键字传递这个结构的实例,效果很好。
现在我想把它作为一个参数传递给一个迭代器方法,而迭代器方法本身将值传递给其他迭代器方法--但是不允许使用in
,这意味着每次将值传递给一个方法时都会复制该值。
这里的上下文是一个包含视频游戏保存状态的结构,迭代器方法是一个“加载”方法,它在Unity game engine(使用迭代器实现协同)中将保存数据的处理扩展到几个帧上。load方法比较复杂,因此需要将其分解为几种方法。
示例:
struct SaveData{
// large data
}
// Async loading - can spread processing across frames (yay!) but copies lots of data (boo!)
IEnumerator LoadAsync(SaveData saveData) {// wish I could use 'in' here!
// use some part of saveData
yield return;
// use more of saveData
yield return InnerLoad(saveData); // wish I could use 'in' here!
}
IEnumerator InnerLoadAsync(SaveData saveData) {// wish I could use 'in' here!
// use saveData
yield return;
}
// Synchronous loading - very efficient (yay!) but blocks, causing an unacceptably long delay (boo!)
void LoadSynchronous(in SaveData saveData){
// use some part of saveData
// use more of saveData
InnerLoadSynchronous(in saveData);
}
void InnerLoadSynchronous(in SaveData saveData){
// use saveData
}
我理解为什么一般情况下in
不允许用于迭代器(例如,如果迭代器/coroutine的持续时间超过值的所有者,该怎么办?)-所以我可以看到为什么最外层的迭代器函数需要一个副本了。但是对于内部调用,由于它们是用yield return
调用的,所以内部迭代器的使用时间不会超过内部迭代器,所以似乎应该有某种方法在中使用。
这里有没有我遗漏的语言特性,或者我可以使用一个很好的模式来解决它?我认为用一个外部类包装该类型是可行的,但这似乎有点混乱,当然仍然需要一个副本,因为我不能有
ref
或in
成员。
但是对于内部调用,由于它们是用yield return调用的,内部迭代器的使用时间不会超过内部,所以似乎应该有一些方法可以使用。
你少了点什么。我们举一个简单的例子:
public class C
{
public static void Main()
{
var enumerator = Outer(3);
Console.WriteLine("Enumerating 1");
enumerator.MoveNext();
Console.WriteLine("Enumerating 2");
enumerator.MoveNext();
var innerEnumerator = (IEnumerator)enumerator.Current;
Console.WriteLine("Enumerating Inner 1");
innerEnumerator.MoveNext();
}
public static IEnumerator Outer(int i)
{
yield return null;
Console.WriteLine("Yielding Inner");
yield return Inner(i);
}
public static IEnumerator Inner(int i)
{
Console.WriteLine($"Inner {i}");
yield break;
}
}
这将打印:
Enumerating 1
Enumerating 2
Yielding Inner
Enumerating Inner 1
Inner 3
(SharpLab)。
正如您所看到的,inner
不是直接枚举的。编译器生成的inner
实现将编译器生成的IEnumerable
返回给outer
的调用方,直到该调用方显式调用MoveNext
时,才执行inner
的主体。
但是,调用inner
的时间要早得多。编译器生成的inner
实现完全执行,并返回生成的IEnumerator
,就在上面的产生inner
之后。因此inner
需要将变量i
存储在编译器生成的类中的某个位置,这就是它不能是in
的原因。
Boost.Any Any库支持类型安全地存储和获取任意类型的值。当你需要一个可变的类型时,有三种可能的解决方案: 无限制的类型,如 void*. 这种方法不可能是类型安全的,应该象逃避灾难一样避免它。 可变的类型,即支持多种类型的存储和获取的类型。 支持转换的类型,如字符串类型与整数类型之间的转换。 Any实现了第二种方案,一个基于值的可变化的类型,无限可能的类型。这个库通常用于把不同类型的东西
我看到的所有在Swift中定义DSL的博客帖子都使用尾随闭包,并使用闭包参数$0。这使得代码冗长,而且我认为很难看。(例如:https://mecid.github.io/2019/01/30/creating-dsl-in-swift) 有没有办法避免这样的代码? 到处都是0美元。 Kotlin通过“带接收器的扩展函数”避免了这种情况(请参阅:带T.()的Kotlin函数签名意味着什么?)。 S
本文向大家介绍Java中避免NullPointerException的方法总结,包括了Java中避免NullPointerException的方法总结的使用技巧和注意事项,需要的朋友参考一下 Java中避免NullPointerException的方法总结 在字符串常量上调用equals 如果strOject == null,那下面一种方法就会抛出NullPointerException 用val
问题 你在类中需要重复的定义一些执行相同逻辑的属性方法,比如进行类型检查,怎样去简化这些重复代码呢? 解决方案 考虑下一个简单的类,它的属性由属性方法包装: class Person: def __init__(self, name ,age): self.name = name self.age = age @property def n
我正在使用一个由其他人编写的C++库,它(不幸的是imo)实现了几个封装在类中的算法,这些类的行为可以通过作为模板参数传递的参数(参数通常也是类)进行微调。例如,可能有这样一个类模板: 我想用这个库编写一个程序,它需要根据运行时信息创建的实例。我的问题是,假设有、和有效类型可以为、和传递,那么当我想实例化的不同spezialization时,我可能需要在代码中的某个位置创建多达分支。例如,在运行时
问题内容: 我有一个包含一些键(字符串)和值(POJO)的地图 我想遍历此映射并更改POJO中的某些数据。 我继承的当前代码将删除给定的条目,并在对POJO进行一些更改后将其重新添加。 这不能很好地进行,因为在遍历地图时您不应该修改地图(方法已同步,但ConcurrentModificationException仍然出现) 我的问题是 ,如果我需要遍历地图并更改值,我可以使用的最佳实践/方法是什么