[英]Const array of closures taking a mutable reference to a struct with lifetime parameter in Rust
我在Rust項目中有以下情形:
struct Foo<'a> {
stuff: &'a i32,
}
因此,我告訴編譯器,我的Foo
結構擁有對某些內容的引用,因此我必須給它一個終身以使其正常工作。
現在,我聲明一下:
type FooFunc<'a> = &'a dyn Fn(&'a mut Foo<'a>) -> bool;
const funcs: [FooFunc; 4] = [
&|f| { *f.stuff = 0; false },
&|f| { *f.stuff = 1; true },
&|f| { *f.stuff = 2; true },
&|f| { *f.stuff = 3; true },
];
並嘗試從Foo
的“方法”內的該const數組調用一個閉包:
impl<'a> Foo<'a> {
fn bar(&mut self, i: usize) -> bool {
funcs[i](self)
}
}
關於生命周期的推理,這應該沒問題,因為對Foo
結構的self
引用具有生命周期'a
(確保事物不會超過'static
,即閉包的生存期),因此閉包應該能夠將self
接收為沒有任何問題的參數。
借閱檢查器對此表示同意,但仍然報告一個我不理解的錯誤:
error[E0308]: mismatched types
--> src/main.rs:7:18
|
7 | funcs[i](self)
| ^^^^ lifetime mismatch
|
= note: expected type `&'static mut Foo<'static>`
found type `&'static mut Foo<'a>`
note: the lifetime 'a as defined on the impl at 5:6...
--> src/main.rs:5:6
|
5 | impl<'a> Foo<'a> {
| ^^
= note: ...does not necessarily outlive the static lifetime
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> src/main.rs:7:18
|
7 | funcs[i](self)
| ^^^^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the method body at 6:5
--> src/main.rs:6:5
|
6 | / fn bar(&mut self, i: usize) -> bool {
7 | | funcs[i](self)
8 | | }
| |_____^
告訴我(在note
標記中), the lifetime 'a as defined on the impl at 5:6 does not necessarily outlive the static lifetime
, the reference is valid for the static lifetime but the borrowed content is only valid for the anonymous lifetime #1 defined on the method body at 6:5
。 盡管提供此類錯誤消息的編譯器令人驚嘆,但我仍然不明白問題出在哪里。
談到第二個note
(這是一種(嘗試)解釋該問題的note
),我無法理解借來的內容是用於const數組還是用於自我引用,但無論哪種情況:
如果“借用的內容”是const數組,那么即使分配了與函數體匹配的匿名生存期,也為什么會有問題? 閉包只需要對作為參數傳遞的引用進行操作,並通過轉移返回值的所有權來返回,而不是通過返回具有可能導致問題的奇怪壽命的引用來返回。
如果“借來的內容”是自我參考,那又為什么呢? 好的,自我引用不再是'a
,而是另一個引用(稱為'b
),它包含在'a
,因此不應該超過'static
,對不對?
當然,我在這里缺少什么,任何幫助將不勝感激。
注意 :這篇文章中的所有代碼只是我正在嘗試實現的“體系結構”的簡化版本-當然,您可以以簡單的方式輕松實現示例代碼中看到的邏輯,但這不是事實我需要。 我想在我的結構上有一個要執行的操作表(這樣的想法是使元素閉包接受&mut
引用)並從我的結構的“方法”中運行這些操作。 實際項目中的實際類型是[Option<[FooFunc<'a>; 6]>; 256]
[Option<[FooFunc<'a>; 6]>; 256]
[Option<[FooFunc<'a>; 6]>; 256]
,因此我們要說的是一個很大的二維“表”,我想用match
語句實現該表將變得非常不愉快,尤其是考慮到我經常重用FooFunc
。
線型type FooFunc<'a> = &'a dyn Fn(&'a mut Foo<'a>) -> bool;
不說“A FooFunc
是任何壽命到閉合這需要任何壽命的基准(對基准Foo
相同的壽命的)”。 相反,它說:“ FooFunc<'a>
是對具有特定生存期'a
的引用,該閉包引用了該特定生存期'a
的引用(對具有相同特定生存期'a
的Foo
的引用), 每個所謂的關閉時間 。”
此外,當您在項目聲明中省略生命周期( [FooFunc; 4]
)時,可以推斷為'static
。 (這是因為類型本身不能超過其類型參數,但是該項目必須為'static
,因此唯一有效的生命周期參數也為'static
。)因此funcs
是對閉包的引用數組,這些閉包僅接受&'static mut Foo<'static>
。
您可能想要的是type FooFunc<'r> = &'r for<'a, 'b> dyn Fn(&'a mut Foo<'b>) -> bool;
,盡管由於其他地方的可變性問題,此操作仍然失敗。 什么,說是“A FooFunc<'r>
是壽命的參考'r
到它接受任何壽命的引用的封閉Foo
與任何壽命(后者壽命隱式會超越第一壽命)秒。” 'r
仍將被推斷為'static
但這沒關系,因為這就是您所擁有的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.