我有一个值,我想存储这个值和一个引用 在我自己类型的价值中:

struct Thing {
    count: u32,
}

struct Combined<'a>(Thing, &'a u32);

fn make_combined<'a>() -> Combined<'a> {
    let thing = Thing { count: 42 };

    Combined(thing, &thing.count)
}

有时,我有一个值,我想存储这个值和它的引用 相同结构中的值:

struct Combined<'a>(Thing, &'a Thing);

fn make_combined<'a>() -> Combined<'a> {
    let thing = Thing::new();

    Combined(thing, &thing)
}

有时,我甚至不取值的参考,我得到 同样的错误:

struct Combined<'a>(Parent, Child<'a>);

fn make_combined<'a>() -> Combined<'a> {
    let parent = Parent::new();
    let child = parent.child();

    Combined(parent, child)
}

在每一种情况下,我都会得到一个值“does”的错误 活得不够长”。这个错误意味着什么?

前言:我寻求的是一个解释,而不仅仅是一个解决方案。我已经知道解了。

尽管花了几天时间研究MSDN上关于基于任务的异步模式(TAP)、async和await的文章,但我仍然对一些更精细的细节感到困惑。

我正在为Windows商店应用程序编写一个日志记录器,我想同时支持异步和同步日志。异步方法遵循TAP,同步方法应该隐藏所有这些,看起来和工作起来都像普通方法。

这是异步日志的核心方法:

private async Task WriteToLogAsync(string text)
{
    StorageFolder folder = ApplicationData.Current.LocalFolder;
    StorageFile file = await folder.CreateFileAsync("log.log",
        CreationCollisionOption.OpenIfExists);
    await FileIO.AppendTextAsync(file, text,
        Windows.Storage.Streams.UnicodeEncoding.Utf8);
}

现在对应的同步方法…

版本1:

private void WriteToLog(string text)
{
    Task task = WriteToLogAsync(text);
    task.Wait();
}

这看起来是正确的,但它不起作用。整个程序永远冻结。

版本2:

嗯. .也许任务还没有开始?

private void WriteToLog(string text)
{
    Task task = WriteToLogAsync(text);
    task.Start();
    task.Wait();
}

这将引发InvalidOperationException:在promise类型的任务上不能调用Start。

版本3:

嗯. .的任务。runsynchrontically听起来很有希望。

private void WriteToLog(string text)
{
    Task task = WriteToLogAsync(text);
    task.RunSynchronously();
}

这将引发InvalidOperationException:对于未绑定到委托的任务,例如异步方法返回的任务,不能调用runsynchronically。

版本4(解决方案):

private void WriteToLog(string text)
{
    var task = Task.Run(async () => { await WriteToLogAsync(text); });
    task.Wait();
}

这个作品。所以,2和3是错误的工具。但1 ?1和4有什么不同?是什么导致1结冰?任务对象是否有问题?是否存在不明显的死锁?

每当我使用:sav命令时,它都会以新名称保存文件,并在Vim中打开新文件。

是否可以使用新名称保存文件,但保留原始名称以供编辑?

据我所知,引用/指针别名会阻碍编译器生成优化代码的能力,因为它们必须确保在两个引用/指针确实别名的情况下生成的二进制行为正确。例如,在下面的C代码中,

void adds(int *a, int *b) {
    *a += *b;
    *a += *b;
}

当clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)编译时,它会发出-O3标志

0000000000000000 <adds>:
   0:    8b 07                    mov    (%rdi),%eax  # load a into EAX
   2:    03 06                    add    (%rsi),%eax  # load-and-add b
   4:    89 07                    mov    %eax,(%rdi)  # store into a
   6:    03 06                    add    (%rsi),%eax  # load-and-add b again
   8:    89 07                    mov    %eax,(%rdi)  # store into a again
   a:    c3                       retq

这里代码存储回(%rdi)两次,以防int *a和int *b别名。

当我们显式地告诉编译器这两个指针不能与restrict关键字别名:

void adds(int *restrict a, int *restrict b) {
    *a += *b;
    *a += *b;
}

然后Clang将发出一个更优化的版本,有效地执行*a += 2 * (*b),如果(正如restrict所承诺的那样)*b没有通过赋值给*a而被修改,则等价:

0000000000000000 <adds>:
   0:    8b 06                    mov    (%rsi),%eax   # load b once
   2:    01 c0                    add    %eax,%eax     # double it
   4:    01 07                    add    %eax,(%rdi)   # *a += 2 * (*b)
   6:    c3                       retq

由于Rust确保(除了不安全的代码)两个可变引用不能别名,我认为编译器应该能够发出更优化的代码版本。

当我测试下面的代码并使用-C opt-level=3——emit obj用rustc 1.35.0编译时,

#![crate_type = "staticlib"]
#[no_mangle]
fn adds(a: &mut i32, b: &mut i32) {
    *a += *b;
    *a += *b;
}

它生成:

0000000000000000 <adds>:
   0:    8b 07                    mov    (%rdi),%eax
   2:    03 06                    add    (%rsi),%eax
   4:    89 07                    mov    %eax,(%rdi)
   6:    03 06                    add    (%rsi),%eax
   8:    89 07                    mov    %eax,(%rdi)
   a:    c3                       retq

这没有利用a和b不能别名的保证。

这是因为当前Rust编译器仍在开发中,还没有结合别名分析来进行优化吗?

这是因为即使在安全的Rust中,a和b仍然有可能别名吗?

我认为这有点主观;我不确定意见是否一致(我见过许多返回引用的代码片段)。

根据对我刚才问的这个问题的评论,关于初始化引用,返回一个引用可能是邪恶的,因为(据我所知)它更容易错过删除它,这可能导致内存泄漏。

这让我很担心,因为我已经遵循了一些例子(除非是我想象的事情),并且在相当多的地方这样做了……我误解了吗?它邪恶吗?如果是的话,到底有多邪恶?

我觉得因为我的指针和引用的混合包,加上我是c++的新手,以及完全不知道什么时候用什么,我的应用程序一定是内存泄漏的地狱…

另外,我知道使用智能/共享指针被普遍认为是避免内存泄漏的最佳方法。

我想安装一个包的旧版本(Newtonsoft.Json)。但NuGet回滚:

PM> Install-Package Newtonsoft.Json -Version 4.0.5
Successfully installed 'Newtonsoft.Json 4.0.5'.
Install failed. Rolling back...
Install-Package : Already referencing a newer version of 'Newtonsoft.Json'.

我该怎么做呢?

我正在寻找一些很好的综合阅读材料,关于JavaScript何时通过值传递,何时通过引用,何时修改传递的项会影响函数外的值,何时不会。我还感兴趣的是,给另一个变量赋值是通过引用还是通过值,以及它是否遵循与作为函数参数传递不同的规则。

我已经做了大量的搜索并找到了许多具体的例子(其中许多在SO网站上),从中我可以开始拼凑真实的规则,但我还没有找到一个单独的、写得很好的文档来描述它。

此外,语言中是否有方法来控制是通过引用还是通过值来传递?

下面是一些我想了解的问题。这些只是例子——我实际上是想了解语言所遵循的规则,而不仅仅是具体例子的答案。但是,这里有一些例子:

function f(a,b,c) {
   a = 3;
   b.push("foo");
   c.first = false;
}

var x = 4;
var y = ["eeny", "miny", "mo"];
var z = {first: true};
f(x,y,z);

对于所有不同的类型,x, y和z的内容什么时候在f的范围之外发生了变化?

function f() {
    var a = ["1", "2", "3"];
    var b = a[1];
    a[1] = "4";
    // what is the value of b now for all possible data types that the array in "a" might hold?
}

function f() {
    var a = [{yellow: "blue"}, {red: "cyan"}, {green: "magenta"}];
    var b = a[1];
    a[1].red = "tan";
    // what is the value of b now and why?
    b.red = "black";
    // did the value of a[1].red change when I assigned to b.red?
}

如果我想要创建一个完全独立的对象副本(没有任何引用),最好的实践方法是什么?

在c# 4.0中,我们在System.Threading.Tasks命名空间中有Task。线程和任务之间的真正区别是什么?我做了一些样本程序(从MSDN的帮助),为了我自己的学习

Parallel.Invoke 
Parallel.For 
Parallel.ForEach 

但有很多怀疑,因为想法不是很清楚。

我最初在Stackoverflow中搜索了类似类型的问题,但可能是这个问题的标题我无法得到相同的答案。如果有人知道之前贴在这里的相同类型的问题,请提供链接的参考。

当我这样做的时候:

std::vector<int> hello;

一切都很好。然而,当我把它变成一个引用向量时:

std::vector<int &> hello;

我就会犯可怕的错误

指向引用的指针是非法的

我想把一堆对struct的引用放到一个vector中,这样我就不用管指针了。为什么矢量会为此大发脾气?我唯一的选择是使用指针的向量代替?

我有一个接口声明

Task DoSomethingAsync();

我正在使用MoqFramework进行测试:

[TestMethod()]
public async Task MyAsyncTest()
{
   Mock<ISomeInterface> mock = new Mock<ISomeInterface>();
   mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> });
   ...
}

然后在我的测试中,执行调用await DoSomethingAsync()的代码。测试在这一行就失败了。我做错了什么?