在这个练习场中,我只想为保存某个属性的const泛型参数实现一个方法:https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=3e4d5f9f27912d032308a390a56f5f94
我正在使用一个大小为零的类型,并向其添加一个方法:
pub struct Resource<const N: usize> {}
impl<const N: usize> Resource<N> {
const fn shorten<const M: usize>(self) -> Resource<M>
where
[(); N - M]:, // type existence only ensured if N >= M
{
// Runtime checks, though they should not be needed
if M <= N {
Resource {}
} else {
panic!("Resources can only be shortened")
}
}
}
其思想是,如果N >= M
,则Resource<N>
类型可以被缩短为Resource<M>
。
但是,当我这样使用它时:
pub fn bar<const N: usize>(
resource: Resource<N>,
) -> Result<((), Resource<{ N - 1 }>), Box<dyn std::error::Error>>
where
[(); N - 1]:,
{
Ok(((), resource.shorten::<{ N - 1 }>()))
}
出现以下编译器错误:
error: unconstrained generic constant
--> src/main.rs:43:22
|
43 | Ok(((), resource.shorten::<{ N - 1 }>()))
| ^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); N - M]:`
note: required by a bound in `Resource::<N>::shorten`
--> src/main.rs:8:14
|
6 | const fn shorten<const M: usize>(self) -> Resource<M>
| ------- required by a bound in this
7 | where
8 | [(); N - M]:, // type existence only ensured if N >= M
| ^^^^^ required by this bound in `Resource::<N>::shorten`
我理解(并在其他在线资源中发现)编译器对where
的建议可能会产生误导(因为它不是一个常用的特性)。忽略这个建议,我不确定为什么以及在哪里首先需要这个界限。
在bar
中,shorten
调用是在Resource<N>
上执行的(从参数中清除),返回Resource<{N - 1}>
(从turbo-fish中清除)。
很高兴听到一些更有经验的铁 rust 虫的想法。
2条答案
按热度按时间rkue9o1l1#
编译器不会分析表达式(一般来说这也是不可能的)。它会进行逐字替换。如果你想编译这段代码,你需要用实际使用的值替换
N
和M
:Playground。
vnzz0bqm2#
我的一个同事告诉我,液体类型(如在Haskell中)将允许对类型进行这样的计算,而不是逐字替换,正如在接受的答案中所解释的那样。
Flux project(和publication)似乎解决了这个问题,但这还为时尚早。