小编TSK*_*TSK的帖子

为什么语言设计者认为这些特征不是对象安全的?

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)

rust

5
推荐指数
1
解决办法
301
查看次数

无法移动到共享引用后面

此代码无法编译:

fn main() {
    let x = "".to_string();
    let y = &x;
    let z = *y;
}
Run Code Online (Sandbox Code Playgroud)

编译器错误输出为:

无法移出*y共享引用后面的内容

发生 move 是因为*y具有 type String,但它没有实现该Copy特征

我不太清楚这里发生了什么并寻求解释。

我期待着z获得String和的所有权xy变得无法使用。

rust

5
推荐指数
1
解决办法
904
查看次数

为什么释放序列只能包含读-修改-写而不能包含纯写

对原子对象M执行释放操作A后,M的修改顺序的最长连续子序列包括:

  1. 由执行 A 的同一线程执行写入。(C++20 之前)
  2. 任何线程对 M 进行原子读-修改-写操作。被称为以 A 为首的释放序列。
  • Q1:为什么需要释放顺序的概念?

    A1:参见“释放顺序”是什么意思?

  • Q2:C++20中第一项被删除了吗?

  • 问题 3:为什么读-修改-写操作符合发布顺序,而纯写操作则不然?

    宽松的 RMW 有什么特别之处,可以让它们形成一个链,而不需要成为获取加载和释放存储?是用计算机体系结构术语,还是用 C++ 语言形式主义?或者换句话说,硬件如何支持原子 RMW 的释放序列语义,但具有中断连接的纯存储?

c++ atomic cpu-architecture memory-model stdatomic

5
推荐指数
0
解决办法
86
查看次数

将闭包指定为返回类型的其他方法?

该函数返回一个闭包。用作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)

为什么最后两个例子不起作用?

rust

2
推荐指数
1
解决办法
247
查看次数

标签 统计

rust ×3

atomic ×1

c++ ×1

cpu-architecture ×1

memory-model ×1

stdatomic ×1