Rust:static、const、new 和 traits
Rust: static, const, new and 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
中声明静态变量,例如:
static FOO: Foo = Foo::new();
但我们立即得到
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
所以,如果我们要构造Foo
类型的静态变量,我们应该声明一个类似new
的函数,但它应该是不同的函数,例如:
impl Foo {
const fn const_new() -> Self { Self { } }
}
static FOO: Foo = Foo::const_new();
但是 const
-twins of trait functions 看起来很奇怪。有没有一种惯用的方法来 write/implement 这样的 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)
}
Rust 游乐场上的这个 code。
您可以将 const_new
重命名为 new
。当特征方法和固有方法同名时,总是选择固有方法;它不被认为是模棱两可的。
这样,同一个调用既可以写在const上下文中,也可以写在泛型上下文中,而且没有不寻常的名字。 (我还建议记录这两个函数以相互提及,这样人们就不会假设一个存在另一个不存在。)
也就是说,我不能说这个想法是惯用的;我还没有在我使用过的库中看到它。
让我们拥有简单的特质:
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();
但我们立即得到
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
所以,如果我们要构造Foo
类型的静态变量,我们应该声明一个类似new
的函数,但它应该是不同的函数,例如:
impl Foo {
const fn const_new() -> Self { Self { } }
}
static FOO: Foo = Foo::const_new();
但是 const
-twins of trait functions 看起来很奇怪。有没有一种惯用的方法来 write/implement 这样的 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)
}
Rust 游乐场上的这个 code。
您可以将 const_new
重命名为 new
。当特征方法和固有方法同名时,总是选择固有方法;它不被认为是模棱两可的。
这样,同一个调用既可以写在const上下文中,也可以写在泛型上下文中,而且没有不寻常的名字。 (我还建议记录这两个函数以相互提及,这样人们就不会假设一个存在另一个不存在。)
也就是说,我不能说这个想法是惯用的;我还没有在我使用过的库中看到它。