Rust 不允许我编写这样的代码:
trait MyTrait {
fn foo();
}
impl MyTrait for u8 {
fn foo() {}
}
fn main() {
let v = 1u8;
let o = &v as &dyn MyTrait;
}
Run Code Online (Sandbox Code Playgroud)
where Self: Sized按照编译器的建议添加fn foo()即可使其工作:
trait MyTrait {
fn foo() where Self: Sized;
}
Run Code Online (Sandbox Code Playgroud)
我的第一个问题是,为什么我需要对我不使用的东西进行约束?
此外,如果我理解正确的话,添加where Self: Sized会产生不可分派的函数,这意味着我无法调用o.foo(). (这并不完全适用于非方法函数,只是为了强调其不吸引人的副作用。)我需要其他解决方案来创建可分派函数。另一个解决方案是添加&self作为第一个参数,将函数变成方法,但我找不到直观的解释为什么方法在这里起作用而函数却不起作用。这提出了一个类似的问题:为什么我必须添加一个我不使用的参数(只是为了使代码编译)?
另一个不起作用的例子是:
trait MyTrait {
fn foo(&self) -> &Self;
}
impl MyTrait for u8 {
fn foo(&self) -> &Self {
self
} …Run Code Online (Sandbox Code Playgroud) 此代码无法编译:
fn main() {
let x = "".to_string();
let y = &x;
let z = *y;
}
Run Code Online (Sandbox Code Playgroud)
编译器错误输出为:
无法移出
*y共享引用后面的内容发生 move 是因为
*y具有 typeString,但它没有实现该Copy特征
我不太清楚这里发生了什么并寻求解释。
我期待着z获得String和的所有权x并y变得无法使用。
对原子对象M执行释放操作A后,M的修改顺序的最长连续子序列包括:
- 由执行 A 的同一线程执行写入。(C++20 之前)
- 任何线程对 M 进行原子读-修改-写操作。被称为以 A 为首的释放序列。
Q1:为什么需要释放顺序的概念?
A1:参见“释放顺序”是什么意思?
Q2:C++20中第一项被删除了吗?
问题 3:为什么读-修改-写操作符合发布顺序,而纯写操作则不然?
宽松的 RMW 有什么特别之处,可以让它们形成一个链,而不需要成为获取加载和释放存储?是用计算机体系结构术语,还是用 C++ 语言形式主义?或者换句话说,硬件如何支持原子 RMW 的释放序列语义,但具有中断连接的纯存储?
该函数返回一个闭包。用作impl Fn()闭包类型就可以了:
fn foo() -> impl Fn() {
|| ()
}
Run Code Online (Sandbox Code Playgroud)
但这是行不通的:
fn foo<T: Fn()>() -> T {
|| ()
}
Run Code Online (Sandbox Code Playgroud)
也不是这个:
fn foo<T>() -> T
where
T: Fn(),
{
|| ()
}
Run Code Online (Sandbox Code Playgroud)
为什么最后两个例子不起作用?