Rust 锈病:静态、常量、新特性和特性

Rust 锈病:静态、常量、新特性和特性,rust,traits,Rust,Traits,让我们有一个简单的特点: trait Object { fn new() -> Self where Self: Sized; } 结构实现了这个特性: struct Foo { /* internal fields */ } impl Object for Foo { fn new() -> Self { Self { /* some magic */ } } } 现在我们想在main.rs中声明静态变量,例如:

让我们有一个简单的特点:

trait Object {
    fn new() -> Self
    where
        Self: Sized;
}
结构实现了这个特性:

struct Foo { /* internal fields */ }

impl Object for Foo {
    fn new() -> Self {
        Self { /* some magic */ }
    }
}
现在我们想在
main.rs
中声明静态变量,例如:

static FOO: Foo = Foo::new();
impl Foo {
    const fn const_new() -> Self { Self { } }
}

static FOO: Foo = Foo::const_new();
但我们马上就得到了

错误[]:静态中的调用仅限于常量函数、元组结构和元组变量

因此,如果我们想要构造
Foo
类型的静态变量,我们应该声明一个类似
new
的函数,但它应该是不同的函数,例如:

static FOO: Foo = Foo::new();
impl Foo {
    const fn const_new() -> Self { Self { } }
}

static FOO: Foo = Foo::const_new();
但是
const
-特质函数的孪生子似乎很奇怪。有没有一种惯用的方法来编写/实现这样的
const
副本

更新

为了清楚起见,我在这里扩展了@KevinReid的答案。给定代码工作:

pub trait Object {
    fn new() -> Self;
}

pub struct Foo {}

impl Foo {
    pub const fn new() -> Self { // (1)
        Self {}
    }
}

impl Object for Foo {
    fn new() -> Self { // (2)
        println!("A-HA!");
        Self::new() // no recursion, calls (1)
    }
}

const FOO: Foo = Foo::new(); // calls (1)

fn main() {
    let obj: Foo = Object::new(); // calls (2)
    let foo = Foo::new(); // calls (1)
}

你可以将
const\u new
重命名为just
new
。当特征方法和固有方法具有相同名称时,总是选择固有方法;这并不被认为是模棱两可的

这样,相同的调用可以在常量和泛型上下文中编写,并且没有不寻常的名称。(我还建议记录这两个函数以相互提及,这样人们就不会因为一个存在而认为另一个不存在。)


也就是说,我不能说这个想法是惯用的;我还没有在我使用过的库中看到它。

您可以将
const\u new
重命名为just
new
。当特征方法和固有方法具有相同名称时,总是选择固有方法;这并不被认为是模棱两可的

这样,相同的调用可以在常量和泛型上下文中编写,并且没有不寻常的名称。(我还建议记录这两个函数以相互提及,这样人们就不会因为一个存在而认为另一个不存在。)

也就是说,我不能说这个想法是惯用的;我还没有在我用过的图书馆里看过