[英]How Can I Access `struct` 's Field in a New `type` of That `struct` slice?
[英]How can I store a generator in a struct?
我想這樣做此 :
#![feature(nll)]
#![feature(generators, generator_trait)]
use std::ops::Generator;
struct Container<G: Generator<Yield = i32, Return = ()>> {
generator: G
}
impl<G: Generator<Yield = i32, Return = ()>> Container<G> {
pub fn new() -> Self {
let q = 42;
Container{ generator: || {
yield 2i32 * q;
} }
}
}
fn main() {}
我收到此錯誤:
error[E0308]: mismatched types
--> src/main.rs:12:31
|
| Container{ generator: || {
| _______________________________^
| | yield 2i32 * q;
| | } }
| |_________^ expected type parameter, found generator
|
= note: expected type `G`
found type `[generator@src/main.rs:12:31: 14:10 q:_ _]`
多虧了通用結構的構造函數中的“預期類型參數”錯誤,我更接近了,在impl
之后刪除了通用類型(因為我沒有為任意G
實現該結構。工作:
impl Container<G>
where
G: Generator<Yield = i32, Return = ()>
{ /* ... */ }
impl Container<Generator<Yield = i32, Return = ()>> { /* ... */ }
impl Container<_> { /* ... */ }
我想我找到了答案,但是如果有人有更好的答案,請隨時發布。 我顯然對此不是很了解,或者我不會問。
為了完整性:需要通用G
,因為生成器就像閉包一樣,每個閉包都有不同的類型(不僅是每個聲明-每個實例也是如此),因為它捕獲了不同的環境。
正如泛型結構的構造函數中的“預期類型參數”錯誤指出的那樣,第一個問題是impl
之后的泛型類型。 這意味着該實現是針對外部選擇的T
,但返回的Self
具有類型參數的特定值,即生成器之一。
至於如何更換它,
impl Container<G> where G: Generator<Yield = i32, Return = ()>
這是行不通的,因為盡管G
是有界的(非常嚴格),但仍然沒有人負責選擇特定的G
impl Container<_>
這不起作用,因為類型推斷不適用於結構實現。 這可能是有道理的-除了“構造函數”之外,對於其他任何東西都不是真正合乎邏輯的。
impl Container<Generator<Yield = i32, Return = ()>>
這是行不通的,因為Generator
是一個特征,並且特征對象未設置大小(而此類型參數應被設置大小)。
大小問題可以解決。 經過一些嘗試,我不確定它是否完美,但是在實現中添加Box
可以解決該問題。 注意Box
不屬於Container
; 顯然Box<Generator<...>>
也滿足約束G: Generator<...>
?
我認為這也大大降低了發電機移動的幾率,我認為這不應該發生:
功能
resume
是不安全的,因為它可以在不動的發電機上使用。 進行此類調用后,不可移動的生成器不得再次移動,但是編譯器不會強制執行此操作。
完整的代碼:
#![feature(nll)]
#![feature(generators, generator_trait)]
use std::ops::Generator;
struct Container<G>
where
G: Generator<Yield = i32, Return = ()>,
{
generator: G,
}
impl Container<Box<Generator<Yield = i32, Return = ()>>> {
pub fn new() -> Self {
let q = 42;
Container {
generator: Box::new(move || {
yield 1i32 * q;
yield 2i32 * q;
yield 3i32 * q;
}),
}
}
}
fn main() {}
並非總是適用的技巧是將生成器(或迭代器,這是非常相似的概念)的創建分成一個單獨的函數。 這使您可以使用impl Trait
:
fn container_core(q: i32) -> impl Generator<Yield = i32, Return = ()> {
move || {
yield 1 * q;
yield 2 * q;
yield 3 * q;
}
}
impl<G> Container<G>
where
G: Generator<Yield = i32, Return = ()>,
{
pub fn new(generator: G) -> Self {
Container { generator }
}
}
fn main() {
let x = Container::new(container_core(42));
}
您仍然無法命名x
的類型,因此無法將其存儲在結構中,因此根本的問題尚未解決。 當然,您可以結合以下答案:
impl Container<Box<Generator<Yield = i32, Return = ()>>> {
fn new_boxed(q: i32) -> Self {
Container::new(Box::new(container_core(q)))
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.