generics - 泛型闭包如何存储在泛型结构中?

标签 generics closures rust

我有一个通用结构,我想在其中存储一个闭包。该闭包的参数和返回类型与该结构的最终类型直接相关。我如何定义这样的结构?

我知道的唯一方法是使用 where 关键字复合类型。然而,当尝试编译代码时,编译器会停止并提示 T't 未使用。

我可以通过添加使用 T't 的无用变量来编译它,但我想有一个更好、更正确的理由来这样做。

以下代码 ( playpen ) 可编译。删除无用的变量就不会了:

pub struct GenericContainer<'t, T: 't, F> where F: Fn(&'t [T]) -> Option<&'t [T]> {
    generic_closure: F,
    unused: Option<&'t T>
}

impl<'t, T: 't, F> GenericContainer<'t, T, F> where 
    F: Fn(&'t [T]) -> Option<&'t [T]> {

    pub fn new(gc: F) -> Self {
        GenericContainer {
            generic_closure: gc,
            unused: None
        }
    }

    pub fn execute(&self, slice: &'t [T]) -> Option<&'t [T]> {
        let g = &self.generic_closure;
        let _ = &self.unused;
        g(slice)
    }
}

fn main() {
    let g = GenericContainer::new(|s| if s.len() == 0 {None} else {Some(&s[..1])});
    assert!(g.execute(b"   ") == Some(b" "));
    println!("ok");
}

最佳答案

您处于典型的“更高级别的东西”情况:'tT 仅用于定义类型 F .

首先,对于生命周期,您可以使用 rust 的较高排名的生命周期语法:

where F: for<'t> Fn(&'t [T]) -> Option<&'t [T]>

从而将其从结构类型中删除。

如果对 T 做类似的事情就好了,但是 Rust 目前不支持更高级别的类型。所以你最好的办法可能是遵循编译器的建议,并使用 std::maker::PhantomData

你最终会得到这样的类型:

pub struct GenericContainer<T, F>
    where F: for<'t> Fn(&'t [T]) -> Option<&'t [T]>
{
    generic_closure: F,
    _marker: ::std::marker::PhantomData<T>
}

请注意,在 _marker 前加上 _ 可以防止其被检测为未使用。

然后,您只需更新您的实现:

impl<T, F> GenericContainer<T, F> where 
    F: for<'t> Fn(&'t [T]) -> Option<&'t [T]> {

    pub fn new(gc: F) -> Self {
        GenericContainer {
            generic_closure: gc,
            _marker: ::std::marker::PhantomData
        }
    }

    pub fn execute<'t>(&self, slice: &'t [T]) -> Option<&'t [T]> {
        let g = &self.generic_closure;
        g(slice)
    }
}

关于generics - 泛型闭包如何存储在泛型结构中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29427826/

相关文章:

c - realloc 不适用于二维指针数组

c# - ToList<T>() 与 ToList()

ruby - 如何将多个 block 传递给 ruby​​ 中的方法?

functional-programming - 闭包的确切定义是什么?

rust - 在 trait 中定义一个返回 Self 的默认实现的方法

Rust:异步查找(在谓词中使用等待)

java - 不兼容的类型泛型 Java

ios - Swift 不能将子类作为父类(super class)返回

javascript - 如何在javascript中将变量传递给回调函数

ubuntu - 为什么我的程序比基准测试显示的慢?