我在一個外部庫中有一個通用的高階函式,它接收了一個FnMut,對其進行包裝,并回傳類似于這樣的結果:
fn foo<T> (mut f: impl FnMut(T) ->/span> T) -> impl FnMut(T)->/span> T{
move |t|f(t)
}
我決定寫一個包裝器來處理一個特定的情況:
我決定寫一個包裝器來處理一個特定的情況:
fn bar(f: impl FnMut(&str) -> &str) -> impl FnMut(& str) ->/span> &str{
foo(f)
}
然而,編譯器出錯了,說其中的一個型別不夠通用:
error[E0308]: mismatched types
--> src/main.rs:4:39。
|
1 | fn foo<T>(mut f。 impl FnMut(T) ->/span> T) -> impl FnMut(T)->/span> T{
| -----------------
| |
|預期的不透明型別。
| 找到的不透明的型別。
...
4 | fn bar(f。 impl FnMut(&str) -> &str) -> impl FnMut(& str) ->/span> &str{
| ^^^^^^^^^^^^^^^^^^^^^^^^ 一個型別 是比另一個更通用的
|
=注意。預期相關的type `<impl FnMut<(& str,)> as FnOnce<(&str,)>。 :輸出`
找到相關的type `<impl FnMut<(& str,)> as FnOnce<(&str,)>。 :輸出`。
如果我使用像i32這樣沒有壽命的型別,它的編譯完全正常,而且寫出HRTB也不會改變錯誤。據我所知,編譯器在匹配函式輸出的壽命時遇到了麻煩,但我不知道它為什么會遇到麻煩以及如何解決這個問題。
uj5u.com熱心網友回復:
不幸的是,rust目前不允許你為你的bar例子創建一個足夠普遍的foo。
但是如果你修改了bar,使呼叫者選擇f的生命周期,而不是在所有的生命周期中通用,你可以使它與當前的foo一起作業:
fn foo<T> (mut f: impl FnMut(T) ->/span> T) -> impl FnMut(T)->/span> T {
move |t| f(t)
}
fn bar<'a> (f: impl FnMut(& 'a str) -> &'a str) -> impl FnMut(& 'a str) -> &'a str{
foo(f)
}
這在技術上更具限制性,但對于大多數使用情況,它應該是等同的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/318644.html
標籤:
上一篇:與協議方法型別相同的列舉
