Pular para o conteúdo

De Rust e de C++ para cá

O que traduz, o que não traduz, e o que aqui é desnecessário.

Quem vem de Rust ou de C++ reconhece os nomes, e a tradução é útil — desde que venha com a diferença que mais importa: aqui há um coletor, e por isso a posse é uma disciplina de recurso, não uma garantia de memória.

Rust / C++DataForgeDiferença
Box<T> / unique_ptrPosse.dono(valor)checado em execução, e no check do arquivo
Rc<T> / shared_ptrPosse.compartilhado(valor)igual, e a contagem também é determinística
Weak<T> / weak_ptrPosse.fraco(compartilhado)igual
&TPosse.com(d, acao)o escopo é a ação, e não um tempo de vida no tipo
&mut TPosse.celulaexclusividade conferida em execução
Dropo ao_soltar do donoigual, e também roda no escopo
RAIIdefer e Posse.escopoo defer é da ação, não do bloco
borrow checkerdataforge checkprova o que dá num arquivo; o resto é execução
lifetime no tiponão existee é a ausência que mais se nota

O que aqui é desnecessário#

  • Anotar tempo de vida. Nada aqui devolve uma referência que pode sobreviver ao dono: usar e com recebem uma ação, e o valor não escapa por construção.
  • `clone()` por toda parte. O coletor resolve o compartilhamento de leitura; clonar é sobre quem fecha, e não sobre quem lê.
  • `unsafe`. Não há o que desligar: a integridade da memória não depende desta camada.
  • Mover por padrão. Aqui o padrão é passar a referência; mover é um pedido explícito, porque quase nunca é o que se quer.

E o que é mais fraco, dito sem rodeio#

Em RustAqui
o compilador prova, e o programa não compilao check prova o que dá num arquivo; o resto falha em execução
a regra vale para todo valorvale para o que nasceu de Arcane.Posse
custo zero em execuçãocusto pequeno, mas real: um objeto por recurso
Send/Sync no tiponão há — a travessia de processo confere na hora de atravessar
dataforge
adopt Arcane.Posse as Posse

// O que Rust escreveria com tempo de vida, aqui é escopo de ação:
// o valor emprestado NÃO escapa, porque não há como devolvê-lo.
d := Posse.dono([1, 2, 3])

// Isto lê e devolve um DADO, não a referência:
tamanho := Posse.com(d, lambda v => len(v))
assert tamanho is 3

// Mesmo devolvendo o próprio valor, o dono continua sendo o dono, e
// soltar continua fechando na hora certa.
d.soltar()
assert d.solto() is yes