Rust: Problema de seguimiento para RFC 2126: aclarar y optimizar las rutas y la visibilidad

Creado en 17 sept. 2017  ·  120Comentarios  ·  Fuente: rust-lang/rust

Este es un problema de seguimiento para el RFC "Clarificar y optimizar las rutas y la visibilidad" (rust-lang / rfcs # 2126).

Pasos:

Preguntas sin resolver:

  • ¿Cómo debemos abordar la migración? ¿A través de una alternativa, como se propone, o mediante épocas? Probablemente sea mejor tomar esta determinación con más experiencia, por ejemplo, después de tener una herramienta rustfix en la mano.

  • La sintaxis final para rutas absolutas; Hay más cambios de bicis por hacer aquí en un contexto en el que realmente podemos probar las diversas opciones. En particular, existen algunas ventajas reales de tener las rutas crate:: y extern:: , pero lo ideal sería que pudiéramos hacerlo de una manera más sucinta.

B-RFC-approved C-tracking-issue E-needs-mentor T-lang WG-compiler-front

Comentario más útil

Aquí hay otra instancia que acabo de encontrar que combina la palabra clave crate tanto en un modificador de visibilidad como en una ruta, que parece incluso más probable que la instancia crate use crate... .

Actual:

pub(crate) struct Bar {
    pub(crate) foo: ::Foo,
}

pub(crate) struct Baz(pub(crate) ::Foo);

Con los cambios de este problema de seguimiento:

crate struct Bar {
    crate foo: crate::Foo,
}

crate struct Baz(crate crate::Foo);

Personalmente, encuentro que el nuevo es más confuso que el actual.

Todos 120 comentarios

Ese RFC tiene 4 características distintas y, sin embargo, solo tenemos un problema de seguimiento para todas. ¿Podemos por favor no juntar características dispares como esta?

@ retep998 Como se explicó a lo largo de las discusiones de RFC, estas características están conectadas a través de consideraciones de diseño global. Por ejemplo, proporcionar un mecanismo externo para cambiar el nombre de las cajas está motivado en parte por la eventual desaprobación de extern crate . Podemos y GATE varios aspectos por separado (y probablemente tendrá algunas puertas superpuestas para probar diferentes sintaxis), pero para el debate sobre el diseño general y la estabilización, es importante mantener la coherencia global en mente.

Tener un mecanismo externo para cambiar el nombre de las cajas es algo que ya se ha deseado y necesitado durante años (https://github.com/rust-lang/cargo/issues/1311) y podría haber estado solo bien, pero en cambio se está utilizando como nada más que un peón para apoyar la eliminación de extern crate .

No hemos tenido problemas con tener RFC separados para características estrechamente relacionadas en el pasado (me vienen a la mente los RFC para repr(align(N)) y repr(packed(N)) ), pero ahora afirmamos que cambiar foo/mod.rs a foo.rs está tan estrechamente relacionado con extern:: y crate:: que tienen que estar en el mismo RFC y utilizar el mismo problema de seguimiento.

Solo para asegurarnos de que este punto se mantenga, ya que es un aspecto relativamente sutil de la sintaxis pregunta sin resolver: usar crate como un modificador de visibilidad así como un prefijo de ruta introduce una ambigüedad de análisis entre crate ::absolute::path y crate::relative::path . El uso de una palabra clave contextual introduce la misma ambigüedad y no hay otras palabras clave reservadas que realmente tengan sentido como modificadores de visibilidad.

Por lo tanto, me gustaría (al menos) experimentar con omitir el modificador de visibilidad crate y seguir con el pub(crate) .

No me importaría dividir el punto foo.rs / foo/mod.rs en un problema de seguimiento separado, ya que realmente parece independiente de los cambios en la ruta y el modificador de visibilidad.

En cuanto al cambio de nombre de la caja externa ... ¿ya existe un problema separado para ello? Es muy importante para los cambios de ruta, así que creo que está bien ser parte de este también .

A pesar de mucha discusión hace unas semanas con respecto a la elección de crate como modificador de visibilidad (no un prefijo de ruta), me decepciona ver que, aunque esta elección de palabra clave se incluyó como una 'pregunta sin resolver' en el RFC, aparentemente ahora se ha olvidado. Yo mismo, y varios otros que he notado, encuentro esta opción confusa ya que no es un adjetivo / modificador, y también puede ser ambigua: ¿ crate significa parte de la API pública de la caja? ¡No! Significa local o internal o pub (lished) a la caja (por eso prefiero las últimas palabras clave). Por lo tanto, no estoy exigiendo un cambio inmediato, pero al menos lo reconozco como una pregunta sin resolver en este tema de seguimiento, para que no se olvide con la estabilización.

Es genial que el rediseño de este módulo haya progresado hasta ahora, pero al mismo tiempo es importante que no nos equivoquemos solo para hacer el 'período implícito' y terminemos tomando decisiones sin consultar a la mayoría de los usuarios de Rust. Y, desafortunadamente, creo que las personas involucradas en las discusiones de Github RFC no son representativas de toda la base de usuarios, debido a la gran cantidad de información / comentarios / opiniones que pueden ser desalentadores. Entonces, de alguna manera, eso también debe tratarse.

No está claro cómo terminó la implementación ...

@rpjohnst @ retep998 He abierto un nuevo RFC para discutir foo.rs + foo/ y proponer algunas mejoras a este RFC.

Editar: sugiero que abramos otro RFC para discutir crate como un modificador de visibilidad. Personalmente, me gustaría ver lo contrario: pub(extern) se agregue y se requiera para todos los símbolos publicados externamente. Esto haría que el pub sea ​​el equivalente de pub(crate) en la próxima época.

@rpjohnst

introduce una ambigüedad de análisis entre crate :: absoluta :: ruta y crate :: relativa :: ruta

¿No es crate ::relative::path código inválido de todos modos? ¿No se puede rechazar durante el análisis?

@ est31 No, eso requiere hacer una resolución de nombres durante el análisis, lo cual definitivamente no es algo que queremos hacer. Es una de las partes más molestas del análisis de C y C ++, que tienen ambigüedades similares en torno a que a * b sea ​​una multiplicación o una declaración, y alrededor de a b(c, d); sea ​​una declaración de variable o un prototipo de función.

Si alguna vez comenzamos a permitir dependencias y módulos de nivel superior con el mismo nombre, incluso mezclar la resolución del nombre con el análisis no nos salvará: crate :: some :: item podría ser un crate -visible item de la dependencia some , o un item privado del módulo de nivel superior some .

Para mantener esto en perspectiva, podríamos simplemente resolver arbitrariamente la ambigüedad de una forma u otra y requerir paréntesis para escribir el otro caso (probablemente el caso de ruta absoluta crate -visibility, que parece más raro), pero sigue siendo un caso foot-gun que no necesitamos si nos quedamos con pub(crate) , que ya resolvió la ambigüedad sintáctica.

El uso de crate como modificador de visibilidad y como prefijo de ruta introduce una ambigüedad de análisis entre crate ::absolute::path y crate::relative::path .

Este es un problema pequeño, en mi opinión, dado que tanto las visibilidades en los campos de estructura de tupla como en las rutas absolutas "en línea" son raras.
Actualmente, las rutas siempre se analizan con avidez, por lo que tiene sentido que crate :: x :: y signifique crate::x::y .
Si se desea el significado opuesto, se puede usar pub(crate) ::x::y o crate (::x::y) .

@rpjohnst @petrochenkov, ¿ podría compartir un ejemplo de código donde pub ::relative::path es un código válido? No entiendo todo el asunto de la ambigüedad porque creo que uno de los dos casos no es válido.

Editar: el único lugar donde esto podría ser relevante es dentro de las macros cuando coincide con un calificador de visibilidad + una ruta. Pero esa es una rotura muy pequeña tan aceptable en mi opinión.

@ est31 Parece tener una idea equivocada: no se trata de rutas relativas, nunca son un problema. Se trata de construir el AST antes de saber a qué se refieren los nombres. Aquí tienes una muestra completa:

struct S(crate :: x :: y);

Dado que todavía no puede buscar ninguno de esos nombres, ¿cómo convierte esa cadena de caracteres en un AST? Hay dos respuestas posibles. Uno tiene un campo privado de un tipo y definido en el módulo x de la caja actual. El otro tiene un campo visible crate de un tipo diferente y definido en el nivel superior de dependencia x . No se necesitan macros.

@rpjohnst Veo gracias por aclarar. De hecho, es una ambigüedad.

@rpjohnst

Una solución simple es definirlo analizándolo sin ambigüedades con el modificador de visibilidad de la caja. Si desea analizarlo como una estructura de tupla con un miembro privado del tipo dado, hágalo así:

    struct S(:: crate :: x :: y);

(tenga en cuenta el prefijo :: para indicar la raíz 'espacio de nombres')

Esto es coherente con la forma en que se debe hacer referencia a otros espacios de nombres raíz en los submódulos (por ejemplo, ::std::x::y ).

Creo que sería algo sorprendente eliminar la ambigüedad a crate -as-a-visibilidad. Pero podría ser una buena idea "canonicalizar" esa solución un poco y hacer cumplir que crate:: siempre se usa con un :: inicial (fuera de use s, por supuesto). Como señala, esto aumenta la simetría con rutas similares a ::std::x::y , y deja la forma sin prefijo para rutas verdaderamente relativas ( self:: / super:: / something_in_scope:: ).

¿Deberíamos hacer esto? Permitir crate::x::y en rutas no use hace que crate algo mágico, mientras que hacer cumplir ::crate::x::y coloca al mismo nivel que las dependencias, que es lo que ' Estás tratando de insinuar de todos modos.

@rpjohnst

hacer cumplir que crate:: siempre se usa con un :: inicial (fuera de los usos, por supuesto)

Esto puede ser razonable, al menos para empezar (nada impide que se relaje más adelante).

No soy fanático de la sintaxis use extern::bar::foo o use crate::bar::foo . Parece muy ruidoso. Preferiría un poco de azúcar para esto. Sugiero extern bar::foo para esto.

¿Qué tal agregar una regla implícita más? Importe automáticamente la caja externa en el espacio de nombres raíz, haga una expresión de ruta más coincidente. (No soy bueno en inglés, por favor aprenda mi punto de vista en el siguiente ejemplo)

p.ej

  1. Nuestra estructura de proyecto así:

src
| --lib.rs
| --foo.rs
| --foo
| ---- | --bar.rs

  1. configura una dependencia en Cargo.toml, como
    [dependencies] serde = "3.0.0"

  2. agregamos el mod bar en el mod foo , y agregamos el mod foo en lib.rs,

  3. definimos una función finlib en lib.rs, definimos una función finfoo en foo.rs, definimos una función finbar en bar.rs

Haga que el alcance de la caja externa sea el módulo de nivel superior en la caja, luego podemos escribir código como este en cualquier lugar.

para ruta completa / calificada

::serde::Deserialize
::serde::x::y
::finlib                            // not ::crate::finlib
::foo::finfoo                   // not ::crate::foo::finfoo
::foo::bar::finbar           // not ::crate::foo::bar::finbar

ruta relativa escribir así

serde::Deserialize      // no need to write `use serde`
serde::x::y                   // no need to write `use serde`
finlib                          
foo::finfoo                  
bar::finbar       

Primero buscamos serdefinlibfoo en el alcance del mod actual, si no lo encontramos en el mod supper, hasta el espacio de nombres raíz. si hay un conflicto de nombre, escribimos la ruta completa en su lugar.

también podemos usar self::bar::finbar en foo.rs para evitar buscar nombres.

No puedo encontrar el hilo anterior que discutía esto, pero el compilador solía funcionar de esa manera y causaba problemas importantes para la resolución de nombres. IIRC @pcwalton o @ arielb1 probablemente sepan más.

¿No sería la solución más fácil a esta ambigüedad usar una palabra clave diferente para el modificador de visibilidad crate-local (es decir, el reemplazo pub(crate) )? Por ejemplo, local , como se sugirió muchas veces en discusiones anteriores de RFC. Entonces struct S(local :: x :: y) es distinto de struct S(crate :: x :: y) .

Eso solo introduce otra ambigüedad entre <visibility> <absolute path> y <relative path starting with the new keyword> , ya que la nueva palabra clave tendría que ser contextual.

@rpjohnst ah maldita sea ... ¿Pero no es ése un problema para el que fueron diseñadas las épocas? Por ejemplo: en la época actual solo usamos pub(crate) , y luego, en la próxima época, introducimos una nueva palabra clave no contextual que es más 'ergonómica'.

@ neon64 sí, pero es una afirmación de la RFC de que no requiere una nueva época. Esa afirmación parece no sostenerse.

Se mantiene bien: actualmente no hay ningún código que use las rutas crate o crate:: , por lo que solo se verá afectado el código nuevo. Siempre que elijamos una resolución y la mantengamos, no hay problemas de compatibilidad.

Una cosa que se me ha ocurrido, con disculpas si se ha mencionado antes en una de las discusiones (no recuerdo haberla visto en el último par):

En la última propuesta, tenemos crate:: para referirnos a "en esta caja" y self:: para referirnos a "en este módulo". Esto es un poco inconsistente y potencialmente menos claro de lo que podría ser: por un lado, donde self refiere a "esto", no es intrínsecamente obvio "esto qué " y, a la inversa, por el hecho de que hay un self:: que significa " este módulo", se podría inferir que crate:: podría significar " alguna otra caja", lo cual es una confusión que de hecho se ha mencionado en el hilo.

Una posible solución sería eliminar self:: en favor de mod:: . Entonces tendríamos crate:: para significar "en la caja envolvente más cercana", y mod:: para significar "en el módulo envolvente más cercano", y sería claro y consistente. También podríamos potencialmente resolver el problema donde no es posible hacer referencia a elementos dentro de un fn ámbito de una forma calificada en absoluto mediante la introducción de un fn:: prefijo, que como era de esperar media "en el cerramiento más cercana fn ". (No he pensado en si tendría sentido ir más lejos y también tener cosas como trait:: o impl:: ).

@glaebhoerl esa es una propuesta interesante. Personalmente, creo que se me ha ocurrido la idea de introducir una nueva sintaxis para las rutas absolutas y desaprobar la existente. No estoy seguro de cómo debería verse esta sintaxis, pero describiré una posibilidad a continuación (que sé que se ha flotado antes).

Imagina que tuviéramos la siguiente gramática para caminos:

Path = AbsolutePath | RelativePath
AbsolutePath = 
    | `@` ID? 
    | `@` ID? `::` RelativePath
    | `self` :: RelativePath
    | `super` :: RelativePath
RelativePath = ID (`::` ID)*

Bajo esta gramática, uno haría referencia a cosas de otras cajas comenzando con @crate , por ejemplo:

use <strong i="13">@std</strong>::collections::HashMap;

Uno haría referencia a la caja local con solo @ , por ejemplo:

use @::something::in::my::crate;

(Y use self::something sigue siendo el mismo que hoy, para bien o para mal).

Algo bueno de esto es que las rutas absolutas se distinguen completamente de las rutas relativas, lo que significa que ahora tenemos la propiedad deseable de que uno puede copiar y pegar una ruta desde use en el código y funciona:

fn foo() {
    <strong i="24">@std</strong>::cmp::min(a, b) // OK
}

Esto no es cierto hoy, lo que definitivamente me confunde de vez en cuando.

También eliminamos la ambigüedad de análisis alrededor de crate , por lo que puede hacer pub Foo(crate @::MyType) o lo que sea y funciona bien.

(En general, tener rutas relativas y absolutas que comiencen con el mismo :: ha sido una fuente de dolor muchas veces, es la verdad).

Una cosa que no sé es si @foo es lo mejor. La otra opción que creo que funciona y en la que he pensado es [] :

  • [std]::collections y [crate]::collections // []::collections parece demasiado extraño.

Realmente no creo que debamos introducir nuevos sigilos solo para los caminos. Aplicar un :: inicial en ::crate::foo es suficiente para abordar el comentario de @glaebhoerl y eliminar la ambigüedad del análisis. También se ajusta más al modelo mental previsto para crate:: : es un sustituto del nombre de la caja actual, no un prefijo de ruta como self:: .

(En general, tener rutas relativas y absolutas que comiencen con el mismo :: ha sido una fuente de dolor muchas veces, es la verdad).

No estoy seguro de a qué te refieres con esto. No creo que ninguna ruta relativa comience con :: , ¿verdad?

@nikomatsakis @glaebhoerl Independientemente de si me gustan tus sugerencias o no (de hecho, puedo vivir con ambas), ¿podemos ceñirnos al RFC? Se ha debatido de un lado a otro de muchas maneras y no creo que abrir el debate nuevamente ayude a nadie. Un total de 82 personas han comentado sobre el hilo del último RFC (hubo bastantes discusiones antes), y muchos se sienten muy convencidos al respecto. Creo que sería injusto para ellos introducir un cambio de última hora en la propuesta en este momento, sin darles la oportunidad de revisar el cambio.
Especialmente estoy un poco confundido porque en # 44721 @nikomatsakis cerró la discusión sobre la función con el argumento "hablemos solo de la implementación, por favor".

La notación @ y la notación [] se han propuesto (y yo soy partidario de ambas) pero finalmente no lo lograron, al menos esa es mi impresión, debido a las respuestas negativas de los usuarios. .

Incluso si no hay ningún caso en el que un :: inicial se pueda confundir con una ruta que comienza en un identificador anterior y tiene un :: interno, visualmente no es muy distinto.

Además, es menos sugerente. @ es un mnemónico mejor. Con un :: inicial, debe preguntarse si es como rutas de nombre de archivo, donde / inicial significa root (si está en un sistema Unixy), o si es una abreviatura estándar, donde no la cosa significaría "omitimos el nombre porque es relativo". Con un momento de pensamiento puedes ver que el primero tiene más sentido, pero el caso es que se necesita un momento de pensamiento. @ (o algo así) se distingue instantáneamente tanto para el compilador como para el codificador, lo que facilita la comprensión instantánea de lo que está sucediendo.

¿Cómo es más fácil distinguir un @ inicial que un :: ? :: ya es un mecanismo establecido tanto en Rust como en C ++!

@rpjohnst - ¡Dije cómo en la misma oración estás respondiendo! @ se distingue visualmente. Para expandirse: salta hacia ti. No hay peligro de que el posicionamiento líder frente al interno se confunda en su modelo mental del flujo de fichas.

@ es un token completamente nuevo sin ningún significado, y tomaría mucho más que "un momento de pensamiento" para descifrarlo. Para empezar, confundir un :: con un :: interno no es un problema; no hay ninguna razón por la que alguien tenga que "pensar un momento" para descartar la idea de que un :: podría ser una ruta relativa.

@rpjohnst : sus afirmaciones son verdaderas si se les proporciona suficiente formación sobre lo que significa :: (que se obtiene con la experiencia con C ++ o Rust). Estaba hablando de capacidad de aprendizaje y diferencia intrínseca. "El mismo símbolo usado en un contexto diferente" nunca será tan distinguible como "un símbolo único".

Podría aceptar el argumento de que no vale la pena quemar @ como símbolo único en un caso de uso como este, donde existe una alternativa tolerable.

@Ichoran : Creo que agregar un nuevo token para una determinada semántica ( @ ) a la gramática de Rust no es un paso que deba tomarse a la ligera, y tengo la ligera sospecha de que estamos demasiado cerca de hacerlo con @nikomatsakis y propuesta de otros. Por un lado, porque luego no podemos reutilizarlo para otro propósito más adelante en la vida del lenguaje (supongo que las rutas son tan omnipresentes en el código que el token @ podría aparecer en muchos lugares). También me pregunto cuál es el efecto sobre la percepción de la complejidad del código Rust. Para un novato que no esté acostumbrado, por ejemplo, a C ++, creo (pero no tengo investigaciones sobre esto) Rust es un lenguaje con una notación bastante barroca e intimidante. Uno de los objetivos estratégicos para este año es optimizar la capacidad de aprendizaje y supongo que la accesibilidad de Rust. Entonces, tal vez tengamos que considerar esto cuando nos apetezca @ porque la intuición es que se destacaría en el código (que @rpjohnst creo que con razón cuestiona). ¿Tengo lo suficientemente claro lo que quiero decir con esto?

(Siéntase libre de corregir o aclarar cualquier cosa que afirme, ya que simplemente no tengo tiempo para seguir la discusión sobre la gramática de Rust tan de cerca).

@ est31

Independientemente de si me gustan sus sugerencias o no (de hecho, puedo vivir con ambas), ¿podemos ceñirnos al RFC?

Básicamente estoy de acuerdo. Realmente no quiero involucrarme en grandes discusiones en este momento, ¡es el período implícito después de todo! - pero quería poner la idea @ "ahí fuera" para que hierva a fuego lento en segundo plano. En parte, porque tiendo a ser un poco olvidadizo, y escribir las cosas me ayuda a recordarlas más tarde.

Mi sensación es que en este punto lo correcto es:

  • Implementar el RFC aproximadamente como está escrito.

    • Es posible que queramos, por ejemplo, adoptar la sugerencia de @rpjohnst de ::crate para rutas absolutas, solo para resolver la falta de

  • Adquiera experiencia en su uso.
  • Revise el diseño, teniendo en cuenta las alternativas que se han presentado mientras tanto, y tome las decisiones finales de estabilización.

Este era el espíritu con el que quería escribir mi comentario, aunque supongo que no lo dejé claro. Quizás hubiera sido mejor guardarlo en un archivo privado. : mujer_encogiéndose de hombros:

EDITAR: Además, soy consciente de que @ y [] se recaudaron antes, aunque no recuerdo si la notación @::foo se mencionó antes por ser relativa a la actual caja. Así que no pretendo afirmar la autoría de la idea.

OTOH, la idea que mencioné no se había planteado anteriormente, y no es tanto una modificación del RFC como una extensión del mismo. Además, "La sintaxis final para las rutas absolutas; hay más cambios de bicis por hacer aquí en un contexto en el que realmente podemos probar las diversas opciones". se enumera explícitamente como una pregunta sin resolver en el cuerpo del problema. Estoy de acuerdo en que, en general, deberíamos tratar de evitar volver a litigar las RFC aceptadas, pero no creo que esta situación sea comparable a la que tuvimos, por ejemplo, con rangos inclusivos (ugh).

Vea también este hilo de discusión:

https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678

¡Bienvenido a otro episodio de Great Modules Adventure! La última vez que nos vimos, nuestros valientes aventureros habían llegado por fin a la tierra legendaria, habiendo aceptado RFC # 2126. Allí tomaron un breve respiro y se prepararon para comenzar con el Período Impl. En ese período, se realizó un gran trabajo y, de hecho, se comenzaron a implementar los esquemas del sistema de módulos. Pero he aquí que todavía quedaban algunas cuestiones inquietantes por resolver ... y eso nos lleva a este hilo de discusión.

En un lenguaje menos florido: durante el período implícito, hicimos un gran progreso en la implementación de la RFC “Clarificar y simplificar las rutas y la visibilidad” (junto con una serie de RFC relacionadas). De hecho, progresamos casi demasiado: implementamos un par de variantes diferentes y me gustaría comenzar una discusión sobre lo que realmente queremos.

Me gustaría poder estabilizar este excelente trabajo algún día =) y eso requerirá que escojamos una de las variantes ... de ahí el hilo.

Personalmente soy fanático de la sintaxis @ mencionada por @nikomatsakis. Es conciso y razonablemente autoexplicativo. Tendremos que introducir algún tipo de sintaxis nueva aquí, así que es mejor un carácter especial que un nombre reservado como crate (ugh).

Parece que ahora estamos en condiciones de abordar el segundo puntero externo, especialmente dado que https://github.com/rust-lang/cargo/issues/1311 ahora está resuelto (de hecho, ya debería estar cerrado). Posiblemente podría abordar esto, con un poco de tutoría y una decisión sobre la sintaxis @ frente a crate . ¿Pensamientos?

Se agregaron problemas de seguimiento para las dos pelusas no implementadas.

Se me ocurre que tenemos un pequeño problema de compatibilidad: si queremos que extern crate vuelva implícito, hay un cambio importante involucrado en hacer que eso funcione - extern crate obliga a las cajas a vincularse; lo que puede causar errores si especifica cajas adicionales en Cargo.toml pero no lib.rs que no se enlazan entre sí limpiamente (por ejemplo, panic = desenrollar cajas con panic = abortar, o cajas que exportan el mismo símbolo). ¿Hemos determinado que se trata de una rotura no problemática?

Se me ocurre que tenemos un pequeño problema de compatibilidad: si queremos que las cajas externas se vuelvan implícitas, hay un cambio radical involucrado en hacer que funcione: las cajas externas obligan a las cajas a vincularse; lo que puede causar errores si especifica cajas adicionales en Cargo.toml pero no lib.rs que no se enlazan entre sí limpiamente (por ejemplo, panic = desenrollar cajas con panic = abortar, o cajas que exportan el mismo símbolo). ¿Hemos determinado que se trata de una rotura no problemática?

La única solución que he visto hasta ahora es vincular implícitamente una caja cuando importas algo de esa caja, sin embargo, esto todavía tiene algunos problemas. Hay muchas formas en que las cajas pueden exponer la funcionalidad de formas distintas a la simple exportación de símbolos de óxido para importarlos, como vincularlos en una biblioteca nativa determinada o exportar símbolos #[no_mangle] para resolver algunas dependencias en una biblioteca nativa. Una vez que se elimina extern crate , la única forma de forzar la vinculación de dicha caja es hacer que exporte un símbolo de óxido de placebo para que se importe según sea necesario. No sé quién pensó que era una mejor idea obligar a las personas a utilizar una solución alternativa de este tipo en lugar de ceñirse a extern crate .

Sí, usamos explícitamente este patrón en Firefox: hay una caja de nivel superior gkrust que solo contiene declaraciones de caja externas para cajas que deben estar vinculadas (estas exponen funciones de C externas escritas en Rust que Firefox llama)

Aún puede hacerlo funcionar requiriendo que las personas use cratename; en lib.rs forzar esto.

¿Qué tal tener un atributo #![link_crates(stylo,webrender)] para este propósito? A diferencia de extern crate , no agregaría la caja al árbol de nombres. Darle un nuevo nombre indicaría claramente a los lectores que está incluyendo las cajas solo para vinculación y que la declaración no debe eliminarse, mientras que extern crate .

¿Eso resuelve el problema opuesto?

Oh, ya veo, para las personas en la época de 2015, les permite actualizar su código sin cambiar de época.

Pero esto significa que _todos_ necesitarían usar una clave link_crates . Eso no es ideal.

¿Qué tal tener un atributo #! [Link_crates (stylo, webrender)] para este propósito? A diferencia de la caja externa, no agregaría la caja al árbol de nombres.

¿Qué pasa con las cajas que podrían usarse como cajas de solo enlace, como cajas con símbolos de Rust o ambas?

@whitequark si usa símbolos de esas cajas, obtendrá enlaces gratis como ya es el caso ahora. El atributo estaría en el sitio de uso para que usted, como usuario, decida cómo usar la caja.

@Manishearth

Pero esto significa que todos necesitarían usar una clave link_crates. Eso no es ideal.

No. No he redactado mi propuesta lo suficientemente bien. Quiero mantener intacta la parte donde use cratename::item; tiene el mismo efecto que link_crates . La función link_crates solo debe usarse si no necesita ningún artículo de la caja, pero necesita el enlace. Si importa algún artículo de la caja, obtendrá un enlace como lo propuso el RFC.

Simplemente no creo que tener use cratename; en su código para ese propósito sea bueno porque confundiría a lints y (lo más importante) lectores / escritores de código, y por lo tanto creo que debería haber una función dedicada para ese legítimo (pero rara vez) caso de uso.

@ est31 Bikeshedding en la sintaxis de link_crates , en lugar de tenerlo como un atributo, ¿por qué no hacemos algo como extern crate foo; ?

@ retep998
¡Buena idea! :sonrisa:
https://github.com/rust-lang/rfcs/pull/2166 incluso introdujo extern crate foo as _; para evitar traer el nombre de la caja al alcance / módulo para cajas de solo vinculación.

@ est31 Bikeshedding en la sintaxis de link_crates, en lugar de tenerlo como un atributo, ¿por qué no hacemos algo como extern crate foo ;?

Sin embargo, el objetivo es deshacerse de la sintaxis extern crate a largo plazo.

@alexreg El punto es hacerlo innecesario en el caso común. Eso no significa que deba ser erradicado por completo, tal vez aún sea una buena solución para el caso de borde de una caja que debe vincularse sin que se utilicen elementos de Rust. (Y de todos modos seguirá vivo mientras el compilador admita épocas más antiguas).

@SimonSapin Pero en el futuro, si solo va a ser un caso marginal, tal vez tener una sintaxis especial no tiene sentido, y un atributo (como se propuso anteriormente) tendría más sentido.

Sigo pensando que use foo o use foo as _ deberían ser suficientes aquí, de verdad

De acuerdo con @Manishearth.

Resumiendo mi opinión sobre extern crate; :

Ventajas:

  • extern crate le brinda una lista completa de cajas usadas en la parte superior de su biblioteca. Ahora, con cajas normales esto no es tan relevante, ya que es Cargo.toml, pero si usted tiene ejemplos Esto es muy útil, ya que le da una lista de cajas a la importación. Solo piense, ¿qué pasa si sus ejemplos solo importan un subconjunto de sus dependencias de desarrollo? Esto tiene grandes beneficios cuando se trata de averiguar la API de una nueva caja, también conocidos como beneficios de aprendizaje. Por otro lado, puede mencionar que extern crate puede aparecer en cualquier lugar de la caja, por lo que la lista no tiene que ser exhaustiva, pero por ejemplo, esto es menos relevante. Siempre podemos cambiar la caja externa para que solo funcione en la raíz de la caja si queremos.

Desventajas:

  • extern crate es una molestia menor, ya que significa más cosas para escribir al agregar una caja. Creo que esta es la razón por la que muchas personas están en contra de extern crate pero para mí no es la razón que la motiva.
  • Veo que extern crate es parte de una operación: renunciamos a extern crate pero obtenemos la distinción entre importación-desde-propia-caja e importación-desde-caja-externa. Esta es una característica mucho más útil y supera en mi opinión las desventajas de la capacidad de aprendizaje con ejemplos / pruebas de código. Esta es la razón motivadora por la que estoy de acuerdo con la eliminación de extern crate .

extern crate le ofrece una lista completa de cajas usadas en la parte superior de su biblioteca. Ahora, con cajas normales, esto no es tan relevante como Cargo.toml, pero si tiene ejemplos, esto es muy útil ya que le brinda una lista de cajas para importar.

No veo cómo esto es relevante para la discusión aquí; este es un punto en contra de una RFC ya fusionada.

@Manishearth Estaba respondiendo más a @ retep998 aquí, quien sugirió mantener una caja externa. Y no, un punto no es ilegítimo o irrelevante solo porque esté en contra de una RFC ya fusionada. Es necesario reflexionar y conocer las ventajas y desventajas de las decisiones. Todavía podemos, por ejemplo, eliminar la caja externa de lib.rs pero mantenerla por hello_world.rs por los beneficios de ergonomía y capacidad de aprendizaje (para los usuarios de la biblioteca, no para sus autores).

Es irrelevante porque lo que se está discutiendo (en el comentario de Peter al que usted responde) son cajas de solo enlaces; que son un caso de uso de nicho suficiente que "enumerar todas sus cajas externas en la parte superior" es un beneficio marginal. Especialmente si tiene dependencias que _no_ también son cajas de solo enlace (esto solía no ser cierto para Firefox, pero ahora lo es).

Si su punto es más general acerca de que la caja externa implícita no se aplica a las pruebas (y no específicamente a las cajas de solo enlace), ese es un punto interesante, pero realmente no estoy de acuerdo con él porque va a ser más confuso cuando se usa solo en la mitad del código.

Entonces, si no me equivoco, el único punto de implementación restante aquí es # 48719. ¿Alguien está abordando eso ahora? Si no, puedo intentarlo, supongo ...

Sí, estamos probando cosas en el n. ° 50260

El sábado 28 de abril de 2018 a las 9:15 a.m. Alexander Regueiro [email protected]
escribió:

Entonces, si no me equivoco, el único punto de implementación restante aquí es

48719 https://github.com/rust-lang/rust/issues/48719 . Hay alguien

abordando eso ahora? Si no, puedo intentarlo, supongo ...

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-385187379 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/ABivSMyg6L4nQ1O7nMcvY4JCGjWKRiq3ks5ttJWhgaJpZM4PaPWi
.

48722 está listo. @Manishearth ¿ podrías actualizar el OP, por favor :)

@ mark-im @Manishearth https://github.com/rust-lang/cargo/issues/1311 también está completo, por lo que tal vez valga la pena cambiar ese punto por una casilla de verificación y marcarlo. Sin embargo, tengo curiosidad: ¿cuál es el enfoque cuando no se usa Cargo, avanzando? (No es que nadie en su sano juicio evite Cargo ...)

@alexreg El mecanismo que usa Cargo para decirle a rustc que cambie el nombre de una caja es igualmente accesible para las personas que no usan carga: --extern name_rustc_sees=path_to_dep.rlib .

Parece que pronto habremos terminado toda la etapa de implementación, cuando https://github.com/rust-lang/rust/pull/47992 aterrice, de hecho. ¿Me estoy perdiendo algo? Feliz de ayudar a mover esto si quedan algunos bits y bobs por hacer.

Sí, está en camino. Necesito terminar eso, lo que probablemente haré temprano.
la próxima semana.

El jueves 3 de mayo de 2018 a las 7:51 p.m. Alexander Regueiro [email protected]
escribió:

Parece que pronto habremos terminado toda la etapa de implementación, cuando

47992 https://github.com/rust-lang/rust/pull/47992 tierras, de hecho. Soy

¿Me falta algo? Feliz de ayudar a mover esto si hay algunos bits y
bobs restantes por hacer.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-386494018 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/ABivSDYFonDWvxZEdxWXoykroaL2mJPxks5tu8I_gaJpZM4PaPWi
.

@Manishearth Buenas cosas.

@aturon con https://github.com/rust-lang/rust/pull/50260 aterrizado, ¿está todo implementado?

¿Alguien consiguió el enlace al plan que se propuso después del RFC? ¿El que más se asemeja a lo que realmente se implementó? (donde las importaciones de --extern cajas se agregan al preludio, etc.)

Dado que este es un cambio tan significativo, ¿tal vez debería actualizarse el RFC?

Los RFC generalmente no se actualizan; no son una especificación final. Son un
herramienta de construcción de consenso.

El lunes, 18 de junio de 2018 a las 9:43 p.m., ¿quién? ¡¿Yo?! [email protected] escribió:

Dado que este es un cambio tan significativo, ¿tal vez debería actualizarse el RFC?

-
Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/rust-lang/rust/issues/44660#issuecomment-398247665 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AABsij-Iwwb7vf4qBrsq9KFFqhuIbkVBks5t-Fc3gaJpZM4PaPWi
.

@ mark-im Esa publicación de discurso se mantiene dentro del espíritu del RFC. Compare el resumen del RFC con esa publicación, es casi lo mismo, más allá de los pequeños detalles. Hubo RFC donde el equipo decidió hacer un cambio totalmente diferente, pero este no es uno de ellos.

Todo eso es cierto, pero sería bueno que todo estuviera en un solo lugar. Aunque entiendo el desafío logístico de eso ...

🔔 🔔 Tenga en cuenta que ya está lista una vista previa de la edición de principios de

@aturon La última actualización, y la última reunión del grupo de trabajo del módulo, resultó en https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678/205 , que específicamente decía " reducido a una propuesta de núcleo único, con dos variantes ". Hasta donde yo sé, eso seguía siendo cierto. Tuve la impresión de que Nightly había implementado ambos, a través de indicadores de funciones, para respaldar la experimentación con ambos.

Parece que la edición eligió una de las dos variantes, la eligió para admitirla sin indicadores de funciones y la documentó en la guía de edición. ¿Dónde se discutió eso? Porque hasta donde yo sé, ni el grupo de trabajo del módulo ni el equipo de lang participaron allí.

Consulte https://internals.rust-lang.org/t/relative-paths-in-rust-2018/7883 para ver una nueva propuesta, basada en la vista previa de 2018. En particular, esta propuesta proporciona más consistencia y uniformidad entre el módulo raíz y los submódulos, y usa la misma resolución de nombre tanto en declaraciones use como en usos directos de rutas en el código.

Hola, solo mis 2 centavos en ::some::path vs crate::some::path . Prefiero el último, principalmente porque es más fácil de leer en inglés simple y no deja una puntuación loca a la izquierda.

¡Echa un vistazo y deja tus comentarios aquí!

Espero que esto sea lo que quisiste decir. Después de revisar un gran cambio en la caja de futuros, en el que todos los pub(crate) s se cambiaron a crate , estoy más convencido de que usar crate tanto en importaciones como como visibilidad El modificador se siente antinatural y confuso.

crate enum Either<T, U> {
    A(T),
    B(U),
}

Lo encuentro especialmente confuso cuando los dos se usan juntos:

crate use crate::foo;

Como mencioné en el problema de lint para intentar que todos cambiemos , eso me entristecería mucho, y probablemente me gustaría implementar un lint de terceros para hacer lo contrario, para usarlo en las bibliotecas que mantengo: detener a la gente de convertir pub(crate) a solo crate .

(Nota: no estoy comentando sobre ninguna otra parte de los cambios, que parecen buenos para la coherencia, solo el cambio de pub(crate) a crate ).

@seanmonstar Con los cambios adicionales propuestos al sistema de módulos en la próxima edición preliminar, espero que crate::foo se vuelva más raro, y crate use crate:: parece una ocurrencia especialmente rara.

Con el sistema de módulos en la vista previa inicial de 2018, necesitaría escribir crate:: incluso para referencias más profundas en su caja. Con el sistema de módulos propuestos, sólo se necesitaría crate:: para las referencias arriba en su cajón (por ejemplo, de foo.rs a lib.rs, o de foo / bar.rs a foo.rs), pero no por referencias abajo en el cajón (por ejemplo, de lib.rs a foo.rs, o desde foo.rs a foo / bar.rs). Y, en general, esperaría reexportar (ya sea a través de pub use o crate use ) para reexportar algo de un módulo más profundo en un módulo de nivel superior, no al revés.

Entonces, en general, me sorprendería ver crate use crate::foo; .

Y, sin embargo, en un proyecto en el que estoy trabajando, tengo exactamente este escenario. Tengo un módulo que contiene varios ayudantes "genéricos", y luego otro módulo que define un rasgo base + combinadores, y dado que hacen uso de un par de ayudantes genéricos, he reexportado para ayudarme a mí mismo en otras partes del caja:

Actualmente:

// in filter/mod.rs
pub(crate) use ::generic::{Combine, Func};

// in filters/foo.rs
use ::filter::{Filter, Func};

La pelusa querrá que cambie esto a:

// in filter/mod.rs
crate use crate::generic::{Combine, Func};

Entonces, no estaba tratando de pensar en una hipótesis que nadie pueda encontrar. Es real.

Estoy totalmente de acuerdo con @seanmonstar. No sobrecarguemos esta palabra clave a menos que tengamos que hacerlo (lo cual no hacemos).

Sí, tienes razón en que las reexportaciones _usualmente_ burbujean, pero ser reexportadas _lateralmente_ también es una cosa, como señala Sean. Es algo que también estoy considerando hacer para la caja de servo-medios, ya que los archivos se dividen bastante bien, pero eso solo significa muchas importaciones comunes en todas nuestras implementaciones de nodos.

¿Será posible continuar declarando lo que se usa en un módulo y posiblemente requerir un uso explícito, tal vez como un atributo de caja? Prefiero poder saber al mirar un archivo fuente lo que está dentro de su alcance. Tener un par de líneas de importaciones de nivel raíz al comienzo de un archivo fuente ayuda a dar un contexto de lo que realmente está sucediendo dentro de él, en lugar de tener todas las dependencias externas implícitamente en el alcance, y ayuda mucho al refactorizar.

Después de haber probado la conversión en una de mis cajas, quería mencionar como algunos otros que he visto hablando de esto, no estoy convencido de usar crate como modificador de visibilidad en lugar de pub(crate) es una mejora. Mi razonamiento aquí es que el apodo de caja se usa bastante, y solo pegarlo frente a los elementos lo hace un poco complicado (me recuerda a la sopa de palabras clave que obtienes en algunos idiomas, como public static void main() Java - al menos Rust tiene el tipo de retorno al final). pub(crate) al menos retiene el pub para que sea más obvio que crate ocupa de la visibilidad en este contexto.

Aquí hay otra instancia que acabo de encontrar que combina la palabra clave crate tanto en un modificador de visibilidad como en una ruta, que parece incluso más probable que la instancia crate use crate... .

Actual:

pub(crate) struct Bar {
    pub(crate) foo: ::Foo,
}

pub(crate) struct Baz(pub(crate) ::Foo);

Con los cambios de este problema de seguimiento:

crate struct Bar {
    crate foo: crate::Foo,
}

crate struct Baz(crate crate::Foo);

Personalmente, encuentro que el nuevo es más confuso que el actual.

Cuando leí por primera vez el RFC para convertir pub(crate) en crate pensé que sonaba como una obviedad. pub(crate) parece muy extraño comparado con el resto de la sintaxis de Rust relacionada en esta área.

Pero...

Después de convertir un pequeño juego de Piston a Rust 2018 y verlo de primera mano, debo admitir que simpatizo con @seanmonstar y otros comentan que tener un crate desnudo por todas partes fue cognitivamente discordante. No puedo estar seguro de si naturalmente me acostumbraría a esto con el tiempo o no.

Como han dicho otros, parece que la palabra clave significa algo muy diferente en ambos contextos.

use crate::menu::{Sound, Volume};

crate mod color;

...

/// A type for storing text and an associated color it should
/// be drawn as.
crate struct ColoredText {
    crate color: types::Color,
    crate text: &'static str,
}

Quiero dejar claro que me gusta mucho el resto de esta propuesta (las actualizaciones del sistema de módulos).

Me complace que pub(crate) parezca un poco torpe y también extraño, pero también un crate siente un poco fuera de lugar.

¿Podríamos considerar una palabra clave diferente aquí en lugar de reutilizar crate ?

@ neon64 Sugirió internal que suena razonable, pero podría haber otros. Dado que podemos agregar palabras clave en Rust 2018, ahora tenemos la oportunidad de considerar esto.

internal parece más pesado que pub(crate) . No es más corto y es una palabra clave nueva.

¿Qué tal int ? :PAGS

Dentro ( ins ), interno ( int ), protegido ( pro ), local ( loc ), secreto ( sec ), inner ( inn ) hay muchas alternativas a la palabra clave crate .

Sin embargo, ¿ int será confuso para los desarrolladores de C / C ++? (Palabra clave entera)

como programador, cuando ves pub lo tratas como público, si quieres introducir otro nivel de visibilidad, necesitas que sea un adjetivo para mantener la coherencia. Por lo que recuerdo, pub significaba publicar inicialmente y en ambos casos pub (crate) se siente más natural. Crate es una palabra clave extraña para eso.
Creo que es mejor dejar pub (crate) como está o agregar una abreviatura del adjetivo.

También creo que la dificultad para nombrar se debe al hecho de que pub es una abreviatura, si fuera público, creo que no sería un problema llamarlo privado o interno y olvidarlo.

Personalmente, no veo el problema con pub(crate) . La sintaxis es clara e inequívoca a primera vista y coherente con Rust real. No creo que tengas que escribir esto con la suficiente frecuencia como para que 5 pulsaciones de tecla adicionales sean un problema.

@UtherII

La razón por la que necesitamos un nombre corto para pub(crate) es porque muchos (quizás incluso la mayoría ) de los usos actuales de pub serán reemplazados por él.

En Rust 2018, el uso de pub para elementos efectivamente privados (porque aparecen en módulos privados) será una advertencia. En su lugar, se debe usar pub(crate) para tales artículos. Esta convención mejorará la legibilidad del código: un artículo es visible para otras cajas si y solo si está marcado como pub , mientras que actualmente si es visible para otras cajas puede no ser obvio de un vistazo.

Lo siento, accidentalmente creé un nuevo problema para esto en lugar de responder a este hilo. Vaya, soy bastante nuevo en github y simplemente hice clic en un botón que me hizo iniciar sesión en lo que pensé que respondía aquí, pero que en realidad estaba creando un nuevo problema. Pegaré lo que escribí en el nuevo número aquí, y mi nuevo problema se puede eliminar, lo siento.

Dado que el manual de edición sugería que las personas dejaran comentarios aquí, decidí hacerlo.

Realmente no me importa crate :: o :: para acceder a elementos desde la raíz de la caja. :: Sin embargo, es lo que ya es la sintaxis, así que si es posible tener tanto crate :: como :: creo que deberían usarse ambos. La forma en que lo veo es que el nuevo sistema de cajas sugerido con respecto a las rutas es esencialmente equivalente a la sintaxis anterior, con la única diferencia de que ya no necesita usar la palabra clave extern, y las cosas son más accesibles en lugar de tener que usarlas explícitamente en los submódulos se importan esencialmente implícitamente en todas partes.

La única otra adición parece ser que inicia la raíz de la caja con crate :: en lugar de ::. Prefiero comenzar con solo ::, ya que esto es consistente con la forma en que lo aprendí originalmente, sin embargo, puedo ver que las personas que aún no han aprendido el sistema de módulos encuentran que comenzar con crate :: es más intuitivo. ¿Por qué no permitir ambas formas de sintaxis? ¿Hay alguna razón por la que no sea factible tener ambos? Si ambos pueden ser apoyados, apoyo completamente el apoyo a ambos. Si solo se puede admitir uno, me inclino más hacia :: tal como es a lo que me he acostumbrado, aunque puede ser más fácil para los novatos aprenderlo como caja :: y puedo actualizar trivialmente mi comprensión del mismo para serlo, entonces tal vez mi motivación sea egoísta.

Básicamente, en última instancia, no me importa, pero personalmente prefiero ::, pero creo que apoyar a ambos sería ideal, aunque si se debe seleccionar uno y la gente piensa que comenzar con crate :: es superior para los novatos, entonces no No me opongo a esto.

¿Cómo se supone que funciona #[path] con módulos anidados en Rust 2018? (https://github.com/rust-lang/rust/issues/35016#issuecomment-409185342)

IIUC, en este momento, dados dos archivos src/lib.rs y src/bar.rs , no hay X que se puedan sustituir en:

mod foo {
    #[path = "X/bar.rs"]
    mod bar;
}

de manera que se encontrará el módulo bar.rs , porque la ruta a bar.rs siempre será src/foo/X/bar.rs que no es válida porque el directorio foo no existe.

Dado que estamos buscando un buen nombre para un reemplazo de pub(crate) y el equipo central todavía está buscando comentarios, me gustaría compartir mi experiencia y ofrecer una sugerencia.

En una caja que escribí, encontré que escribir pub(crate) todas partes me enfurecía. Así que simplemente lo acorté a pub y sin darme cuenta exporté muchos símbolos que no necesitaban ser visibles fuera de la caja. UPS. 😛 (En mi caso específico, no es realmente un problema, porque la caja es interna y no está publicada, ¡pero aún así! La conveniencia sobre la corrección). Así que sí, creo firmemente que necesitamos algo mejor que una combinación de dos palabras clave para transmitir visibilidad a nivel de caja. .

Pero no creo que crate sea ​​la palabra clave correcta para ello (consulte más arriba los comentarios de otras personas sobre este tema), y creo que algunas otras palabras clave sugeridas pierden el punto al abordar el problema desde la perspectiva de la raíz de la caja; el problema radica en la perspectiva del módulo, es decir, la línea de código específica que contiene la palabra clave. En otras palabras, el código no está tratando de proporcionar "localidad de caja", está tratando de exportar la referencia desde el módulo donde está definida.

En ese sentido, me gusta la palabra clave export (incluso si es posible confundirla con extern , pero tal vez eso sea discutible ya que extern crate está muerto?) export struct Foo; parece muy legible y se alinea con algunos otros idiomas (ish). No pude encontrar ninguna mención de export como palabra clave, en este RFC o en otro lugar. Así que también está a su favor.

Para completar, cubre los casos de uso presentados por @seanmonstar , @johnthagen , et al .:

export use crate::generic::{Combine, Func};

// Or even better using relative paths
export use ::generic::{Combine, Func};
export struct Bar {
    export foo: crate::Foo,
}

export struct Baz(export crate::Foo);
use crate::menu::{Sound, Volume};

export mod color;

// ...

/// A type for storing text and an associated color it should
/// be drawn as.
export struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}

Dicho todo esto, estoy a favor de matar pub(crate) con fuego. Incluso prefiero crate , FWIW.

@parasyte El problema que veo con export es que podría confundirse con "esta caja exporta ____" (que es para lo que está pub ), pero veo cómo estás defendiendo una perspectiva diferente.

Parece que la mayoría de la gente está pub(crate) acuerdo en que crate , que ahora se usa en otros contextos, puede resultar discordante como reemplazo. Asegurarnos de que hemos considerado completamente otras palabras clave (potencialmente nuevas) parece que sería un muy buen uso del tiempo antes de que Rust 2018 establezca esto en piedra.

Sin embargo, no he escuchado ningún comentario "oficial" si esto todavía está abierto a discusión.

Con el interés de introducir algunas palabras más en la línea de la sugerencia de @johnthagen en que export parece más pub que pub(crate) ):

shared use ::generic::{Combine, Func};
shared struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}
global use ::generic::{Combine, Func};
global struct ColoredText {
    export color: types::Color,
    export text: &'static str,
}

También podríamos seguir los pasos de Java y usar algo como protected , pero no estoy seguro de que sea particularmente fácil de entender. También hay local (en el sentido de crate-local), pero creo que global es menos probable que confunda (por ejemplo, local podría ser _file_-local).

¿Cómo se sentiría la gente acerca de pub(cr) o incluso solo cr ?

Usar crate parece demasiado bueno para dejarlo pasar. Ya es una palabra clave, su uso anterior en extern crate va a desaparecer. Su otro uso ya está relacionado con la visibilidad pub(crate) .

Si entrecierra los ojos un poco usando crate como adjetivo no suena tan desconcertante. Palabras como 'casa' se pueden usar como adjetivos muy bien. IANAEnglishProfessor.

Creo que reexportar un elemento visible en la caja no es muy problemático. Personalmente, solo he reexportado un elemento en un elemento principal directo del módulo que lo define, lo que significa que (probablemente) desee usar self lugar de crate (el caso de organización de código de seanmonstar a pesar de ). P.ej.

    mod detail {
        crate struct Foo;
    }

    crate use self::detail::Foo;

Usar crate como una visibilidad combinada con una ruta absoluta a un tipo (nuevamente usando el ejemplo de seanmonstar) parece más problemático: crate struct Foo(crate crate::Bar); en lugar de pub(crate) struct Foo(pub(crate) ::Foo); . Mi única esperanza es que esta construcción no sea popular y, por lo tanto, la transición no creará esta sopa de cajas. Los usuarios pueden evitar esto importando explícitamente:

use crate::Bar;

crate struct Foo(crate Bar);

Me gusta la sugerencia de share o algo así. give , provide , deliver , offer , serve , post , forward .. .Si debe ser un adjetivo, todos se pueden transformar con un sufijo: shared , givable , providable , etc.

Para elegir JavaScript por un momento, ES6 ni siquiera tiene un concepto de paquete versus módulo integrado en el lenguaje. Solo hay módulos. La palabra clave export en ES6 siempre exporta la referencia del módulo; entonces depende de otro módulo para import esa referencia por ruta si quiere usarla.

Esto no es muy diferente de pub y use , respectivamente. y supongo que de ahí viene parte de la confusión con el uso de una palabra clave export . pub(crate) es en realidad una especie de nicho. Es por eso que opté por usar pub en el pasado. ; (

El problema del modificador de visibilidad crate se ha extraído a # 53120. Allí deben continuar más debates y decisiones.

El problema de los cambios mod.rs se ha extraído a # 53125. Allí deben continuar más debates y decisiones.

El problema de la depreciación extern crate , así como tener use crate_name::foo y crate_name::foo Just Work ™ se ha extraído de https://github.com/rust-lang/rust/ cuestiones / 53128. Allí deben continuar más debates y decisiones.

El problema de elegir un sistema de ruta de módulo se ha extraído de https://github.com/rust-lang/rust/issues/53130.

Habiendo extraído todos los bits de este tema en temas separados; Por la presente cierro este.

@Centril : https://doc.rust-lang.org/unstable-book/print.html#extern_prelude enlaces aquí. ¿Dónde se está discutiendo esto? Si esta información realmente falta, ¿podría agregarla al OP?

@ sanmai-NL, ¿puedes refrescarme la memoria sobre lo que fue el "preludio externo"?

Si es solo la capacidad de hacer use some_crate::foo::bar; entonces debería ser https://github.com/rust-lang/rust/issues/53128.

Algo de esto se está discutiendo en https://github.com/rust-lang/rust/issues/54230.

@ sanmai-NL Creo que ese problema es principalmente para el diagnóstico.

extern_prelude es crate_name::foo::bar fuera de las rutas use (importación).

@Centril

¿Puedes refrescarme la memoria sobre lo que fue el "preludio externo"?

En general, "preludio" se usa actualmente para todos los nombres que están dentro del alcance de toda la caja y no están adjuntos a un módulo específico. (Hay muchos de esos en realidad).

@petrochenkov Entonces, ¿cuál es el preludio "externo" en relación con eso?

@alexreg
Las cajas pasadas con --extern están dentro del alcance de toda la caja mientras no están adjuntas a ningún módulo específico.

Sería genial si estas pepitas de información, sin importar cuán volátiles sean, se registran en alguna fuente oficial de documentación. Esp. si hay menciones externas del concepto, por ejemplo, en el libro Inestable. Sin embargo, no estoy diciendo que los mantenedores que implementan estos conceptos deban hacer eso.

@petrochenkov Gracias, tiene sentido.

Habiendo extraído todos los bits de este tema en temas separados; Por la presente cierro este.

@Centril Problemas de seguimiento en el enlace de la versión beta actual aquí. ¿Actualizaría el comentario original con la información más reciente para que la gente no tenga que escribir los comentarios?

¿Fue útil esta página
0 / 5 - 0 calificaciones