Que tengamos el rasgo simple:

trait Object {
    fn new() -> Self
    where
        Self: Sized;
}

Y la estructura implementó este rasgo:

struct Foo { /* internal fields */ }

impl Object for Foo {
    fn new() -> Self {
        Self { /* some magic */ }
    }
}

Ahora queremos declarar la variable estática en main.rs, por ejemplo:

static FOO: Foo = Foo::new();

Pero inmediatamente llegamos

Error [e0015]: Las llamadas en las estadísticas están limitadas a funciones constantes, Tuple Structs and Tuple Variants

Por lo tanto, si queremos construir variables estáticas de tipo Foo, deberíamos declarar una función como new, pero debe ser una función diferente, por ejemplo:

impl Foo {
    const fn const_new() -> Self { Self { } }
}

static FOO: Foo = Foo::const_new();

Pero const - Las funciones de los gemelos de rasgo parecen muy extraños. ¿Hay alguna forma idiomática de escribir / implementar tales contrapartes const?

ACTUALIZACIÓN

Amplíe la respuesta de @Kevinreid para mayor claridad aquí. El código dado funciona:

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)
}

Esta rust traits

0
Michael Galuza 29 may. 2021 a las 16:02

1 respuesta

La mejor respuesta

Puede cambiar el nombre const_new a solo new. Cuando un método de rasgo y un método inherente tienen el mismo nombre, siempre se selecciona el método inherente; No se considera ambiguo.

De esta manera, la misma llamada se puede escribir en contextos const y genéricos, y no hay un nombre inusual. (También sugeriría documentar las dos funciones para mencionarse mutuamente, por lo que las personas no asumen que porque uno existe el otro no).

Dicho esto, no puedo decir que esta idea es idiomática; No lo he visto hecho en una biblioteca que he usado.

2
Kevin Reid 29 may. 2021 a las 13:54