簡體   English   中英

閉包的常量數組,在Rust中使用壽命參數對結構進行可變引用

[英]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 lifetimethe 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

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=17034fe41c74d65d7a296ae812f19945

線型type FooFunc<'a> = &'a dyn Fn(&'a mut Foo<'a>) -> bool; 說“A FooFunc是任何壽命到閉合這需要任何壽命的基准(對基准Foo相同的壽命的)”。 相反,它說:“ FooFunc<'a>是對具有特定生存期'a的引用,該閉包引用了該特定生存期'a的引用(對具有相同特定生存期'aFoo的引用), 每個所謂的關閉時間 。”

此外,當您在項目聲明中省略生命周期( [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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM