我试图通过传入&str
切片来在const
上下文中创建Uuid
,但我不断收到各种错误。
This answer给了我非常量的解决方案,但由于引用,它似乎在const
中不起作用。
如何使用哈希的前16个字节作为Uuid
的输入?这在const
环境中实际上可能吗?
struct ExampleId(Uuid);
pub const fn from_str(value: &str) -> ExampleId {
// Hash the str slice to get a "random" value
let hash: const_sha1::Digest =
const_sha1::sha1(&const_sha1::ConstBuffer::from_slice(value.as_bytes()));
// This gives a 20 byte hash
let bytes: [u8; 20] = hash.bytes();
// We only need 16 of these for a UUID but it doesn't seem possible to do this in a const context
let bytes_16: [u8; 16] = bytes[..16].try_into().unwrap();
ExampleId(Uuid::from_bytes(bytes_16))
}
const EXAMPLE: ExampleId = ExampleId::from_str("example_id");
error[E0277]: the trait bound `[u8; 16]: From<&[u8]>` is not satisfied
--> crates/bevy_diagnostic/src/diagnostic.rs:22:46
|
22 | let bytes_16: [u8; 16] = bytes[..16].try_into().unwrap();
| ^^^^^^^^ the trait `~const From<&[u8]>` is not implemented for `[u8; 16]`
|
= note: required for `&[u8]` to implement `~const Into<[u8; 16]>`
= note: required for `[u8; 16]` to implement `~const TryFrom<&[u8]>`
= note: required for `&[u8]` to implement `~const TryInto<[u8; 16]>`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `bevy_diagnostic` due to previous error
为了增加上下文,目前此代码使用u128
,看起来像ExampleId::from_u128(0x8EE938B3184729691BCCD346823B631C)
,用户必须生成一个唯一的128位数字/十六进制。为了使它更容易,我希望允许传入一个字符串来生成ID。UUID是API的公开部分,因此不能更改,这意味着我需要从任意字符串切片生成UUID。最后,因为这个ID在编译时是必需的,所以这需要作为const
函数来完成。
2条答案
按热度按时间ogq8wdun1#
在const函数中还不允许使用for循环,但是你可以使用while循环:
hfwmuf9z2#
我的意思是有this dumb solution copying the bytes one by one,也许在某个地方有一个宏:
如果你愿意使用
unafe
,你也可以让编译器为你生成所有的复制代码:与Sven Marnachs解决方案不同,这两种解决方案都不会对最终数组进行两次初始化,但它们都有其他缺点,无可否认,在这种情况下,除非您多次使用它,否则这并不是一个真正的问题。