微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么不能将 `stackalloc` 表达式分配给 `Span<T>` 参数?

如何解决为什么不能将 `stackalloc` 表达式分配给 `Span<T>` 参数?

考虑以下方法 (fiddle):

void test(Span<int> param)
{
    //Fail,the stackalloc'ed buffer Could be exposed.
    param = stackalloc int[10];
}

void test2(Span<int> param)
{
    //OK
    Span<int> local = stackalloc int[10];
}

我不明白为什么 param = stackalloc int[10]; 会产生错误

'Span' 类型的 stackalloc 表达式的结果不能在此上下文中使用,因为它可能会暴露在包含方法之外

Span一个 ref struct 但(尽管它的名字)它仍然是一个值类型,所以对 param 的任何修改都不会反映在调用者对象上。

我认为 param一个具有初始值的局部变量,我不明白为什么 test2 会编译而 test 不会。

stackalloc int[10]test 的返回值如何脱离方法的作用域?

解决方法

Sinatr 在评论中发布了一个链接 (here the relevant part),帮助我将整个代码置于 Span safety 的上下文中。

在方法 test 中,参数 param 可以安全返回,因为我们可以假装它就像一个局部变量,用调用者给定的值初始化(因此,在方法外部,可以安全返回)。

当一个局部变量被标记为可以安全返回时,编译器将阻止对其进行任何赋值,这些值不能安全返回(stackalloc 表达式可以安全地转义到方法的顶级范围,但不安全显然要回来)。

该方法为 void 的事实并不重要(无论是作为提问者的我,还是编译器),因为这条规则是通用的(我认为处理这些极端情况并没有太大好处)。

为完整起见,此代码无法编译:

void test2(Span<int> param)
{
    //Fail,because local is marked safe to return
    Span<int> local = param;
    local = stackalloc int[10];
}

这是我一直在寻找的缺失部分。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。