我有以下数据结构(简化):
use std::collections::HashMap;
pub struct StringCache {
// the hashmap keys point to elements stored in `storage`
// so never outlive this datastructure. the 'static refs are never handed out
table: HashMap<&'static str, usize>,
storage: Vec<Box<str>>,
}
Run Code Online (Sandbox Code Playgroud)
关于此处引用的生命周期向 Rust“撒谎”是合法/定义的行为吗?对我来说,这感觉就像违反了类型系统。这个数据结构的公共API健全吗?为了完整起见,以下是完整的实现:
use std::mem::transmute;
impl StringCache {
pub fn intern(&mut self, entry: &str) -> usize {
if let Some(key) = self.table.get(entry) {
return *key;
}
let idx = self.storage.len();
self.storage.push(entry.to_owned().into_boxed_str());
// we cast our refs to 'static here.
let key = …Run Code Online (Sandbox Code Playgroud) Rust 中的结构体std::cell::Ref定义如下:
pub struct Ref<'b, T: ?Sized + 'b> {
// NB: we use a pointer instead of `&'b T` to avoid `noalias` violations, because a
// `Ref` argument doesn't hold immutability for its whole scope, only until it drops.
// `NonNull` is also covariant over `T`, just like we would have with `&T`.
value: NonNull<T>,
borrow: BorrowRef<'b>,
}
Run Code Online (Sandbox Code Playgroud)
评论// NB(我假设 Nota bene / Nasty Bug 或其他什么?)暗示以下定义不起作用,因为这会违反noalias(它们是否意味着后端的 LLVM 属性?):
pub struct Ref2<'b, T: ?Sized …Run Code Online (Sandbox Code Playgroud) 默认初始化数组时,其元素默认初始化的顺序是 C++ 标准定义的吗?
\n举个例子,下面的C++程序是否保证打印严格升序的内存地址?
\n#include <iostream>\nstruct Foo{\n Foo() {\n std::cout << this << std::endl;\n }\n};\nint main() {\n delete[] new Foo[10];\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n我在标准的 9.4.1 初始化器,常规下找到了以下内容:
\n\n\n7 默认初始化 T 类型的对象意味着:(...)
\n(7.2)\xe2\x80\x94 如果 T 是数组类型,则每个元素都默认初始化。
\n
我是否正确地假设这意味着它未指定,或者文档中的其他地方也没有对此进行澄清?
\n这个答案声称它已经定义(根据(a)),但是(afaict)没有提供任何证据。
\n请注意,我并不是试图在初始化之前引用数组本身(Can a (C/C++) array optimization reference itself?),而只是关心初始化顺序的可观察到的副作用。
\nc++ arrays initialization language-lawyer default-initialization
看起来posix \n 命令行实用程序会做一些基于语言环境的花哨 的恶作剧来比较给定的字符串。sort
我扫描了手册页,但似乎找不到一种方法让它使用原始字节值。\n有没有办法让sort(我有 GNU coreutils 版本)的行为像\nqsort(array_of_my_strings, N, strcmp)中那样C?使用其他工具的解决方案sort也可以。
为了演示,我目前得到:
\nprintf "\\xC3\\xBC\\n\\x76\\n" | sort\n\xc3\xbc\nv\nRun Code Online (Sandbox Code Playgroud)\n因为德语元音变音\xc3\xbc似乎与位于 v 之前的 u 进行比较,尽管它\\xC3大于\\x76。
我想要的是
\nprintf "\\xC3\\xBC\\n\\x76\\n" | sort --raw-bytes-please\nv\n\xc3\xbc\nRun Code Online (Sandbox Code Playgroud)\n constexpr size_t byte_count,它是 1、2、4 或 8constexpr bool is_signed,这显然是真或假我想用and为整数类型构造一个typedef/ 。usingTsizeof(T) == byte_countstd::is_signed_v<T> == is_signed
<type_traits>在(或标准库的其他地方)有什么东西可以做到这一点吗?
否则,实现这一目标的最紧凑的方法是什么?
我真的很喜欢一些不会对类型进行硬编码的简短内容,因为这将在多个地方使用,在这些地方引入辅助函数/类型很烦人(它在生成的代码内部......叹息)。
我没有动力
我当前的解决方案:
#include <type_traits>
#include <tuple>
#include <cstddef>
#include <cstdint>
int main(){
constexpr size_t byte_count = 4; // either 1, 2, 4, or 8
constexpr bool is_signed = true; // either true or false
// I would like to have something shorter and less hardcoded than this
using T = std::conditional_t< …Run Code Online (Sandbox Code Playgroud) 当尝试编写或解释cfg诸如以下之类的语句时
#[cfg(all(unix, not(target_arch = "wasm32")))]
Run Code Online (Sandbox Code Playgroud)
从atty板条箱中,我有时不确定unix这里到底意味着什么。(显然它包括wasm?)
是否有 rust 编译器目标属于哪个目标系列的完整列表?
rust 参考资料中的 cfg 文档似乎没有。
我在 Rust 中遇到的一个常见模式是这样的:
struct Foo { /*...*/ }
struct FooProcessor {
foos: Vec<&'??? mut Foo>, // this lifetime is the issue, see explanation below
// other data structures needed for processing Foos ....
}
impl FooProcessor {
// just to make it clear, `self` may outlive `input` and it's `Foo`s
pub fn process(&mut self, input: &mut [Foo]) {
// some example operation that requires random access to a subset
self.foos.extend(input.iter().filter(|f| f.some_property()));
self.foos.sort();
// work some more on the Foos...
// …Run Code Online (Sandbox Code Playgroud)