Quero que o usuário consiga passar a struct e instanciá-la sem uma função construtora, mas não consiga modificar os campos da estrutura sem usar os métodos setter fornecidos na implementação. Isso é possível em Rust sem envolver a estrutura em uma estrutura imutável como Arc/Rc?
Não quero usar um método construtor porque, se a estrutura que está sendo construída tiver muitos campos, parece muito mais limpo para mim (e para o rustfmt clippy linter ) poder ver quais valores estão sendo definidos para campos de estrutura específicos na instanciação. Também evita digitar os argumentos fora de ordem, o que pode ser um problema muito maior se você tiver 2 do mesmo tipo de parâmetro um ao lado do outro nos argumentos.
Eu também preferiria não usar pub(crate)
porque isso ainda deixa a possibilidade de um mantenedor acessar o campo fora de um método de implementação.
mod foo {
pub struct Foo { // Struct is public
bar: usize // Field is private.
}
impl Foo {
// This is the only way I want to allow the user to modify `bar`. I
// explicitly do not want to allow them to directly access struct
// fields such as `let baz = foo.bar` or `foo.bar = 1` from down below.
pub fn set_bar(&mut self, bar: usize) {
self.bar = bar;
}
}
}
fn main() {
let mut foo = foo::Foo {
bar: 0 // ! Compilation fails here because this field is private.
};
// I want this to continue to fail to compile.
foo.bar = 1;
// But I want this to succeed.
foo.set_bar(1)
}
Desculpas se isso for uma duplicata. Procurei por perguntas de instanciação de construtor relacionadas a campos privados e não consegui encontrar nenhuma que lidasse com isso especificamente. O mais próximo é este post de Alika97 , mas não necessariamente lidava com um grande número de campos (e, portanto, parâmetros de função).
Se construir uma estrutura pública com campos privados fora do módulo não for possível/viável, qual é a melhor solução do que um construtor com muitos parâmetros, ou essa é minha única opção se eu não quiser que os campos sejam públicos (mesmo dentro da caixa)?