`Pub` destina-se a indicar público para engradado ou público para módulo? [duplicado]
Para tornar os métodos de um submódulo público, você deve reexportá-los explicitamente ou então tornar o próprio submódulo público:
mod foo {
mod bar {
pub fn baz() {}
}
pub use self::bar::baz;
}
Isso parece indicar que pub
é usado para indicar que algo deve ser público apenas para um módulo (já que você pode optar por não fazer isso)
Mas se você usar um tipo privado definido no contexto externo, obterá um erro se tentar tornar uma função pública envolvendo-o pública no contexto interno, mesmo quando não for reexportado.
mod foo {
struct Foo;
mod bar {
use super::Foo;
pub fn baz(foo: Foo) {}
}
}
resulta em
error[E0446]: private type `Foo` in public interface
--> src/lib.rs:7:9
|
2 | struct Foo;
| - `Foo` declared as private
...
7 | pub fn baz(foo: Foo) {}
| ^^^^^^^^^^^^^^^^^^^^ can't leak private type
Qual é a maneira idiomática de usar a pub
palavra - chave? Deve ser reservado para coisas que são realmente públicas ou pode ser usado para módulos internos?
Respostas
A razão pela qual seu exemplo falha ao compilar é, em última análise, porque a RFC (136) disse isso. (Veja também o problema 22261 )
Que restrições se aplicam a itens públicos?
As regras para vários tipos de itens públicos são as seguintes:
- Se for uma
static
declaração, os itens mencionados em seu tipo devem ser públicos.- Se for uma
fn
declaração, os itens mencionados em seus limites de característica, tipos de argumento e tipo de retorno devem ser públicos.- Se for uma declaração
struct
ouenum
, os itens mencionados em seus limites de característica e nos tipos de seuspub
campos devem ser públicos.- Se for uma
type
declaração, os itens mencionados em sua definição devem ser públicos.- Se for uma
trait
declaração, os itens referidos em seus super-traços, nos limites dos traços de seus parâmetros de tipo e nas assinaturas de seus métodos (veja ofn
caso acima) devem ser públicos.
Em suma, baz
não é permitido pub
porque tem um argumento que é do tipo privado. Assim, se baz
for pub
, permitiria que o pai mod foo
reexportasse baz
fazendo pub use bar::baz;
. É claro que isso não é permitido, e é por isso que o exemplo como um todo é ilegal.
Alguns mencionaram anteriormente que isso pub fn baz
deveria ser permitido e, em vez disso, fornecer um erro de compilação no caso de o módulo pai exportá-lo novamente. No entanto, isso exigiria uma análise estática mais complexa para detectar e, em última análise, não foi feito porque a RFC definiu que é ilegal.
pub
especifica que o item pode ser acessado pelo módulo pai. Se todos os ancestrais do módulo forem pub
, esse item será exportado pela caixa como um todo.
A palavra-chave
pub
torna qualquer módulo, função ou estrutura de dados acessível de dentro de módulos externos. Apub
palavra-chave também pode ser usada em umause
declaração para reexportar um identificador de um namespace.- Documentação de ferrugem
Com a noção de um item ser público ou privado, Rust permite acessos a itens em dois casos:
- Se um item for público, ele pode ser acessado externamente de algum módulo m se você puder acessar todos os módulos ancestrais do item de m. Você também pode potencialmente nomear o item por meio de reexportações. Ver abaixo.
- Se um item for privado, ele pode ser acessado pelo módulo atual e seus descendentes.
- The Rust Reference - Visibilidade e Privacidade