gpt4 book ai didi

function - 缺少顶级功能的实现

转载 作者:行者123 更新时间:2023-11-29 08:25:16 24 4
gpt4 key购买 nike

我正在尝试使一个特征可用于 Rust 中的顶级函数。

trait FnTrait {
fn call(self);
}

impl FnTrait for fn() {
fn call(self) {
self()
}
}

fn foo() {
println!("Hello, World!")
}

fn main() {
FnTrait::call(foo)
}

但是下面的代码无法通过 (Playground Link) 编译

error[E0277]: the trait bound `fn() {foo}: FnTrait` is not satisfied
--> <anon>:16:5
|
16 | FnTrait::call(foo)
| ^^^^^^^^^^^^^ the trait `FnTrait` is not implemented for `fn() {foo}`
|
= help: the following implementations were found:
<fn() as FnTrait>
= note: required by `FnTrait::call`

我发现我可以通过像这样转换 foo 来欺骗它编译

FnTrait::call(foo as fn())

但这很烦人,我程序中的某些函数比foo 更复杂。有什么办法避免类型转换?我的性格有什么问题吗?

最佳答案

Rust 中的每个函数都有自己的类型。如您所见,foo 不是 fn(),而是 fn() {foo};遗憾的是,这不是您可以在源代码中编写的实际类型,这只是编译器消息。存在这种区别是为了让编译器更容易让您将函数作为值传递,同时仍然能够内联调用。

结果是命名函数指针不能在没有强制转换或类型提示的情况下转换为通用函数指针。例如,这有效:

fn foo() {
println!("Hello, World!")
}

fn bar(f: fn()) {
f()
}

fn main() {
bar(foo)
}

但是,我不知道有什么方法可以利用它来使特性发挥作用。

唯一的出路是停止尝试为函数指针实现特性,而是为所有可调用的东西实现它:

trait FnTrait {
fn call(self);
}

impl<F> FnTrait for F where F: FnOnce() {
fn call(self) {
self()
}
}

fn foo() {
println!("Hello, World!")
}

fn main() {
foo.call();
}

(关于 the difference between Fn, FnMut and FnOnce 的半相关回答。)

这将适用于任何可使用该签名调用的东西,包括函数和闭包。缺点是您只能一个这样的实现。您不能为任何其他签名实现此特征。

一个通用实现,或许多特定实现和大量手动转换。选择你的毒药。


顺便说一句:Rust 中没有“顶级函数”这样的东西,至少不是与其他类型的函数不同的东西。函数就是函数,不管它们出现在哪里。实例函数 a.k.a. 方法仍然是常规函数,只是它们的第一个参数称为“self”。

关于function - 缺少顶级功能的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44349422/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com