0% acharam este documento útil (0 voto)
4 visualizações46 páginas

Rust Vs Python Strings

O documento compara o tratamento de strings em Rust e Python, destacando as diferenças entre os tipos String e &str em Rust. Enquanto Python utiliza apenas str, Rust distingue entre a propriedade dos dados e referências, enfatizando a importância do gerenciamento de memória. O texto também fornece exemplos práticos e diretrizes sobre quando usar cada tipo, além de explicar a conversão entre eles.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
4 visualizações46 páginas

Rust Vs Python Strings

O documento compara o tratamento de strings em Rust e Python, destacando as diferenças entre os tipos String e &str em Rust. Enquanto Python utiliza apenas str, Rust distingue entre a propriedade dos dados e referências, enfatizando a importância do gerenciamento de memória. O texto também fornece exemplos práticos e diretrizes sobre quando usar cada tipo, além de explicar a conversão entre eles.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

09/03/2026, 14:52 Rust vs Python Strings

Sou programador Python aprendendo Rust, tenha ótima


didática e faça correlação entre as linguagens, mostre
como o rust trabalha com String vs &str

Pensou por 5s

Claro. Vamos fazer isso do jeito certo: comparando Python com Rust, porque isso acelera
muito o aprendizado.

Visão geral
Em Python, você normalmente usa só str e pronto:

nomePython
= "Gandra" Executar

Em Rust, a história é diferente. Existem dois tipos muito importantes para texto:
String

&str

A diferença principal é:
String = texto dono dos dados, alocado dinamicamente

&str = referência para um texto já existente

Intuição rápida
Pense assim:
String em Rust se parece com algo “mais dono” do valor, parecido com um objeto

mutável de string gerenciado na heap


&str é como uma visão ou empréstimo de um trecho de texto

Em Python, as strings são objetos imutáveis e você quase nunca pensa em posse ou
empréstimo.
Em Rust, isso é central.

[Link] 1/46
09/03/2026, 14:52 Rust vs Python Strings

1. &str : string emprestada


Exemplo

fn main() {
let nome: &str = "Gandra";
println!("{}", nome);
}
Rust

O que está acontecendo?


"Gandra" é uma string literal.

Em Rust, string literal tem tipo &'static str .

Ou seja:

os dados já estão embutidos no binário


a variável guarda uma referência
ela não é dona do texto

Comparação com Python


Em Python:

nomePython
= "Gandra" Executar

Você só enxerga uma string.

Em Rust, esse mesmo caso fica mais explícito: o literal é uma referência para dados fixos.

2. String : string dona dos dados


Exemplo

fn main() {
let nome: String = String::from("Gandra");
println!("{}", nome);
}
Rust
[Link] 2/46
09/03/2026, 14:52 Rust vs Python Strings

Aqui:
é criada uma string dinâmica
os dados ficam na heap
a variável nome é a proprietária desse conteúdo

Comparação com Python


Python também cria objetos de string, mas você não precisa gerenciar nem pensar em
ownership.

Em Rust, String existe quando você precisa de algo como:

construir texto dinamicamente


concatenar
modificar conteúdo
retornar posse de texto

3. Diferença prática: quem pode ser alterado?


&str é imutável por natureza da referência ao texto

fn main() {
let s: &str = "Olá";
println!("{}", s);
}
Rust
Você não consegue “aumentar” esse texto diretamente.

String pode ser modificada

fn main() {
let mut s = String::from("Olá");
s.push_str(", mundo");
println!("{}", s);
}
R t

Comparação com Python


[Link] 3/46
09/03/2026, 14:52 Rust vs Python Strings

Em Python, string é imutável:

s = "Olá"
s += ", mundo"
print(s)
Python Executar

Isso parece mutação, mas na prática Python cria outra string.

Em Rust, String é um buffer mutável. Você realmente pode expandir o conteúdo.

4. Resumo mental que funciona bem


Guarde isso:
&str → “eu só estou apontando para um texto”

String → “eu sou o dono do texto”

Essa distinção é uma das bases de Rust.

5. Exemplo lado a lado com Python


Python

def saudacao(nome: str) -> str:


return "Olá, " + nome
Python Executar

Rust usando &str

fn saudacao(nome: &str) -> String {


format!("Olá, {}", nome)
}

fn main() {
let nome = "Gandra";
let msg = saudacao(nome);
println!("{}", msg);
}

[Link] 4/46
09/03/2026, 14:52 Rust vs Python Strings

O que observar
A função recebe &str porque:

ela só precisa ler


não precisa ser dona da entrada

Ela retorna String porque:

format! cria um novo texto

esse novo texto precisa ter um dono

6. Quando usar &str em parâmetros?


Na maioria dos casos, para receber texto em função, prefira &str .

Exemplo

fn imprimir(texto: &str) {
println!("{}", texto);
}
Rust

Isso é ótimo porque aceita tanto literal quanto String .

fn imprimir(texto: &str) {
println!("{}", texto);
}

fn main() {
let a = "literal";
let b = String::from("dinâmica");

imprimir(a);
imprimir(&b);
}

Comparação com Python


Em Python, uma função recebe str e pronto.
Em Rust, usar &str no parâmetro deixa a função mais flexível e evita mover a posse
desnecessariamente.

[Link] 5/46
09/03/2026, 14:52 Rust vs Python Strings

7. Quando usar String ?


Use String quando você precisa:

ser dono do texto


armazenar texto que vai crescer ou mudar
retornar texto novo
guardar dados de entrada lidos do usuário, arquivo, rede etc.

Exemplo

fn criar_nome() -> String {


String::from("Gandra")
}
Rust

Aqui faz sentido retornar String , porque a função está criando um novo valor.

8. Conversão entre String e &str


Isso é muito importante.

De String para &str

fn main() {
let s = String::from("Olá");
let fatia: &str = &s;
println!("{}", fatia);
}
R t
Também pode usar:

let fatia = s.as_str();


Rust

De &str para String

[Link] 6/46
09/03/2026, 14:52 Rust vs Python Strings

fn main() {
let s: &str = "Olá";
let dono: String = s.to_string();
println!("{}", dono);
}
Rust

Ou:

let Rust
dono = String::from(s);

9. Analogia forte com Python


Pense assim:

Em Python
Você quase sempre manipula referências para objetos sem perceber.

Em Rust
O compilador te obriga a deixar claro:
isso é posse?
isso é empréstimo?
isso pode ser modificado?
isso vai viver por quanto tempo?

Esse rigor é o que dá a Rust segurança de memória sem garbage collector.

10. Exemplo mais didático: leitura versus posse


Rust

fn contar_chars(texto: &str) -> usize {


[Link]().count()
}

fn main() {
let s1 = "abc";
let s2 = String::from("rust");

[Link] 7/46
09/03/2026, 14:52 Rust vs Python Strings

println!("{}", contar_chars(s1));
println!("{}", contar_chars(&s2));
}

Por que &str aqui é melhor?


Porque a função só lê.
Ela não precisa “tomar posse” do dado.

Se você escrevesse assim:

fn contar_chars(texto: String) -> usize {


[Link]().count()
}
Rust

Aí a função consumiria a String , o que geralmente é desnecessário.

11. Diferença importante: String não é igual a str


Isso costuma confundir no começo.

String = tipo possuído, completo, fácil de usar


str = tipo de texto “cru”, geralmente usado por referência, isto é, &str

Na prática, você quase sempre verá:

String

&str

e raramente str sozinho.

12. Um exemplo errado e o motivo


Código

fn main() {
let nome = String::from("Gandra");
let outro = nome;
println!("{}", nome);
}
R t
[Link] 8/46
09/03/2026, 14:52 Rust vs Python Strings

O que acontece?
Isso dá erro, porque:

nome é uma String


String move por padrão

ao fazer let outro = nome; , a posse vai para outro


nome deixa de ser válido

Comparação com Python


Em Python:

nome = "Gandra"
outro = nome
print(nome)
Python Executar

Isso funciona sem drama porque o modelo de memória é outro.

Em Rust, como String é dona dos dados, a transferência de posse importa.

13. Como evitar mover?


Use empréstimo:

fn main() {
let nome = String::from("Gandra");
let outro = &nome;

println!("{}", nome);
println!("{}", outro);
}

Aqui:
nome continua dono

outro só empresta

Isso conecta diretamente com a ideia de &str .

14. Regra prática que vale ouro


[Link] 9/46
09/03/2026, 14:52 Rust vs Python Strings

Para funções:
receber texto → prefira &str
retornar texto novo → use String

Para variáveis:
texto fixo/literal → &str
texto construído/modificado dinamicamente → String

15. Exemplo completo comparando com Python


Python

def adicionar_sobrenome(nome: str) -> str:


return nome + " Silva"

nome = "João"
print(adicionar_sobrenome(nome))
print(nome)

Rust

fn adicionar_sobrenome(nome: &str) -> String {


format!("{} Silva", nome)
}

fn main() {
let nome = "João";
let completo = adicionar_sobrenome(nome);

println!("{}", completo);
println!("{}", nome);
}

Leitura didática
nome entra como &str

a função não consome a entrada


cria um novo texto
[Link] 10/46
09/03/2026, 14:52 Rust vs Python Strings

devolve String

Isso é muito idiomático em Rust.

16. Tabela mental rápida


Situação Python Rust

Texto literal str &str

Texto dinâmico str String

Receber texto sem possuir str &str

Criar/retornar novo texto str String

Mutação de texto nova string é criada String pode crescer/mudar

17. Exemplo idiomático de API em Rust

fn eh_admin(usuario: &str) -> bool {


usuario == "admin"
}

fn main() {
let u1 = "admin";
let u2 = String::from("gandra");

println!("{}", eh_admin(u1));
println!("{}", eh_admin(&u2));
}

Perceba a vantagem: a função aceita os dois casos sem forçar alocação extra.

18. Frase que você deve memorizar


String possui o texto. &str apenas aponta para texto.`

Essa frase resolve metade da confusão inicial.

[Link] 11/46
09/03/2026, 14:52 Rust vs Python Strings

19. Erro comum de iniciante


Muita gente tenta usar String em todo lugar.
Funciona às vezes, mas não é o melhor estilo.

Em Rust idiomático:

use &str para leitura


use String para posse e construção

Isso reduz cópias, evita moves desnecessários e deixa o código mais expressivo.

20. Exemplo final bem claro

fn exibir(texto: &str) {
println!("Texto: {}", texto);
}

fn montar() -> String {


let mut s = String::from("Rust");
s.push_str(" é forte");
s
}

fn main() {
let literal = "Olá";
let dinamica = String::from("Mundo");

exibir(literal);
exibir(&dinamica);

let frase = montar();


println!("{}", frase);
}

O que esse código ensina


literal é &str

dinamica é String

exibir recebe &str porque só lê

montar retorna String porque cria um texto novo

[Link] 12/46
09/03/2026, 14:52 Rust vs Python Strings

Fechamento
A forma mais correta de pensar, vindo de Python, é:

em Python você pensa mais em valor/objeto


em Rust você pensa em posse, referência e tempo de vida

Para strings isso aparece imediatamente com:

String = dono
&str = empréstimo

Regra prática final

fn processa(texto:
Rust &str) -> String

Esse formato aparece o tempo todo em Rust real, porque é um excelente equilíbrio:
entrada por referência
saída com posse

Posso montar agora uma aula 2 mostrando:


ownership, borrowing e lifetime com exemplos comparando Python vs Rust, que é
exatamente o próximo passo natural depois de String e &str .

por que raramente temos str sozinho?

Pensou por um segundo

Ótima pergunta. Esse ponto é fundamental para entender Rust de verdade.

Resposta direta
Raramente existe str sozinho porque str é um tipo de tamanho dinâmico
(dynamically sized type, DST).
Isso significa que o compilador não sabe, em tempo de compilação, quantos bytes um
str ocupa.

E em Rust, quase tudo que fica em variável local, parâmetro por valor ou campo comum
precisa ter tamanho conhecido em tempo de compilação.

[Link] 13/46
09/03/2026, 14:52 Rust vs Python Strings

Por isso, na prática, você quase sempre usa:

&str
Box<str>

dentro de String

mas quase nunca str “nu”.

Comparando com Python


Em Python, você faz:

nomePython
= "gandra" Executar

e não precisa pensar no tamanho, layout, ownership nem nada disso.

Em Rust, o compilador precisa saber com precisão:

quanto espaço alocar


como mover o valor
como armazenar esse valor na stack

Se o tipo não tem tamanho conhecido, ele não pode ser usado sozinho da forma
comum.

O que é exatamente str ?


str é o tipo que representa uma sequência de bytes UTF-8 válida.

Mas ele não carrega, sozinho de forma simples e copiável, um tamanho fixo que permita
algo como:

let x: str = ...;


Rust

Isso não funciona da forma normal porque str tem comprimento variável.

[Link] 14/46
09/03/2026, 14:52 Rust vs Python Strings

Por que &str funciona?


Porque &str não armazena o texto diretamente.
Ele armazena uma referência para o texto.

Essa referência tem tamanho conhecido.

Na prática, &str guarda algo equivalente a:

ponteiro para o início dos bytes


comprimento da fatia

Ou seja, embora o conteúdo apontado tenha tamanho variável, a referência em si tem


tamanho conhecido.

É por isso que isso funciona:

fn main() {
let s: &str = "Olá";
println!("{}", s);
}
Rust

A ideia mental correta


Pense assim:

str = o texto em si, de tamanho variável

&str = um “controle remoto” que aponta para esse texto e sabe onde ele começa e

quanto mede

O controle remoto tem tamanho fixo.


O texto não.

Exemplo análogo com slices


Isso fica mais fácil quando você compara com arrays e fatias.

Array com tamanho conhecido

[Link] 15/46
09/03/2026, 14:52 Rust vs Python Strings

let Rust
a: [i32; 4] = [1, 2, 3, 4];

Aqui o compilador sabe exatamente o tamanho.

Slice

let Rust
s: &[i32] = &a[..];

[i32] sozinho também é um tipo de tamanho dinâmico.

Por isso você quase nunca usa [i32] sozinho, e sim &[i32] .

Com strings é a mesma lógica:

str é como [u8] validado como UTF-8


&str é como uma slice de string

Então str é parecido com [T]


Exatamente.

Essa é uma correlação excelente:

str está para strings


[T] está para arrays/slices

E ambos são DSTs.

Por isso você vê:

&str

&[i32]

e não:

str
[i32]

sozinhos como variáveis comuns.

Por que String existe então?

[Link] 16/46
09/03/2026, 14:52 Rust vs Python Strings

Porque String é um tipo “completo”, com tamanho conhecido, que gerencia um buffer
dinâmico.

String guarda metadados conhecidos, algo conceitualmente como:

ponteiro para heap


capacidade
comprimento

Esses metadados têm tamanho fixo, mesmo que o texto armazenado tenha tamanho
variável.

Então isso funciona:

let Rust
s: String = String::from("Olá");

A variável s não contém diretamente todos os bytes da string dentro dela na stack.
Ela contém uma estrutura de tamanho fixo que administra os bytes na heap.

O erro conceitual mais comum


Muita gente pensa:

“Se &str existe, então str deveria ser uma string normal.”

Mas não.
str não é o equivalente direto de String .

A relação correta é mais ou menos esta:

String → dono de texto dinâmico

str → texto fatiado, sem tamanho fixo, geralmente usado por referência

&str → referência para str

Exemplo do que não funciona

let Rust
texto: str = "abc";

[Link] 17/46
09/03/2026, 14:52 Rust vs Python Strings

Isso falha porque str não pode viver sozinho como variável local comum.

Exemplo do que funciona

let Rust
texto: &str = "abc";

Aqui funciona porque &str é uma referência de tamanho conhecido.

E Box<str> ?
Existe, e é um caso em que você consegue ter um str “possuído”, mas indiretamente:

let s: Box<str> = "Olá".into();


Rust

Aqui o str continua não sendo armazenado “sozinho” na stack.


Ele está dentro de um Box , ou seja, alocado no heap e acessado por ponteiro.

Então, de novo, o padrão se mantém:

o str puro não é usado sozinho


ele precisa estar atrás de um ponteiro ou embutido em outro tipo

Comparação didática com Python


Em Python você trabalha em alto nível:
tudo é objeto
o runtime resolve layout e memória

Em Rust você enxerga mais a estrutura real:

str é um dado sem tamanho fixo


&str é uma referência fina para leitura

String é um dono do buffer

Por isso Rust te obriga a distinguir essas formas.

[Link] 18/46
09/03/2026, 14:52 Rust vs Python Strings

Regra prática para memorizar


Guarde isto:

str sozinho quase não aparece porque:


1. ele tem tamanho dinâmico
2. tipos de tamanho dinâmico geralmente não vivem sozinhos
3. eles costumam aparecer atrás de referência ou ponteiro

Então, em código real, você verá muito mais:

&str
String
Box<str>
Rust

do que:

str
Rust

Tabela mental
Tem tamanho Pode aparecer
Tipo conhecido? sozinho facilmente? Uso comum

str não não tipo base de texto

&str sim sim leitura/empréstimo

String sim sim posse e mutação

Box<str> sim sim posse heap sem


capacidade extra

Frase para decorar


str é para texto o que [T] é para sequência: um tipo fatiável de tamanho dinâmico,

quase sempre usado por referência.

[Link] 19/46
09/03/2026, 14:52 Rust vs Python Strings

Exemplo final que amarra tudo

fn main() {
let literal: &str = "Rust";
let owned: String = String::from("Python");
let boxed: Box<str> = "Go".into();

println!("{}", literal);
println!("{}", owned);
println!("{}", boxed);
}

Aqui:

"Rust" vira &str


String::from("Python") cria dono mutável/dinâmico

"Go".into() cria um Box<str>

Mas str sozinho não aparece como variável comum.

Conclusão
str raramente aparece sozinho porque ele não é um valor de tamanho fixo que o

compilador consiga manipular diretamente como variável comum.


Ele é o “miolo” textual, e normalmente precisamos de algo que o referencie ou encapsule:
&str para emprestar

String para possuir e editar

Box<str> para possuir sem capacidade extra

O jeito mais didático de pensar é:

str = conteúdo textual bruto

&str = visão emprestada

String = dono do buffer

Na próxima etapa, o ideal é eu te mostrar como String faz deref para &str , porque isso
explica por que funções com &str aceitam String tão bem.

[Link] 20/46
09/03/2026, 14:52 Rust vs Python Strings

continue

Pensou por alguns segundos

Perfeito. Agora entra uma peça muito importante do quebra-cabeça:

Por que uma função que recebe &str aceita String ?


Porque Rust faz deref coercion em muitos casos.

Isso parece nome complicado, mas a ideia é simples:

quando um tipo “aponta” para outro, Rust às vezes converte automaticamente a


referência para o tipo esperado.

No caso de strings:

String pode ser vista como str

então &String pode virar &str

Primeiro, veja o exemplo

fn exibir(texto: &str) {
println!("{}", texto);
}

fn main() {
let nome = String::from("Gandra");
exibir(&nome);
}

Isso funciona.

Mesmo que exibir espere &str , nós passamos &String .

Rust converte isso automaticamente para &str .

Comparando com Python


[Link] 21/46
09/03/2026, 14:52 Rust vs Python Strings

Em Python, você não percebe esse tipo de conversão porque tudo já chega de forma bem
flexível:

def exibir(texto: str):


print(texto)

nome = "Gandra"
exibir(nome)
P th E t
Em Rust, a diferença é que os tipos são muito mais explícitos.
Mesmo assim, o compilador ajuda em vários casos com coerções automáticas seguras.

O que é “deref”?
“Deref” vem de dereference, isto é, “seguir” um ponteiro/referência até o dado interno.

Em Rust, alguns tipos sabem como se comportar como se contivessem outro tipo.

String implementa comportamento para ser tratado como str .

Então, conceitualmente:

String contém um buffer textual

esse conteúdo pode ser enxergado como str


portanto &String pode ser usado como &str

Forma explícita vs forma automática


Forma automática

fn exibir(texto: &str) {
println!("{}", texto);
}

fn main() {
let s = String::from("Olá");
exibir(&s);
}

[Link] 22/46
09/03/2026, 14:52 Rust vs Python Strings

Forma explícita

fn exibir(texto: &str) {
println!("{}", texto);
}

fn main() {
let s = String::from("Olá");
exibir(s.as_str());
}

As duas funcionam.

O que está acontecendo por baixo


Quando você escreve:

exibir(&s);
Rust

e s é String , o compilador entende algo como:

1. &s tem tipo &String


2. a função quer &str
3. String pode ser dereferenciado para str
4. então ele converte &String em &str

Isso é parecido com .value ou atributo em Python?


Mais ou menos, mas com uma diferença importante.

Em Python, acessar o conteúdo interno costuma ser algo dinâmico e resolvido em


runtime.
Em Rust, isso é parte do sistema de tipos e é resolvido com segurança pelo compilador.

Então não é “mágica frouxa”; é uma coerção muito controlada.

Exemplo bem didático


[Link] 23/46
09/03/2026, 14:52 Rust vs Python Strings

fn tamanho(texto: &str) -> usize {


[Link]()
}

fn main() {
let literal = "rust";
let dinamica = String::from("python");

println!("{}", tamanho(literal));
println!("{}", tamanho(&dinamica));
}

O que passou para a função?


literal já é &str
&dinamica é &String , mas vira &str automaticamente

Isso é um dos motivos de &str ser o melhor tipo para parâmetros de leitura.

Então por que não receber &String sempre?


Porque &str é mais geral e mais flexível.

Veja:

fn exibir(texto: &String) {
println!("{}", texto);
}
Rust

Agora isso não aceita literal diretamente:

fn exibir(texto: &String) {
println!("{}", texto);
}

fn main() {
let s = String::from("Olá");
exibir(&s); // ok

// exibir("Olá"); // erro
}

[Link] 24/46
09/03/2026, 14:52 Rust vs Python Strings

Já com &str :

fn exibir(texto: &str) {
println!("{}", texto);
}

fn main() {
let s = String::from("Olá");

exibir("Olá"); // ok
exibir(&s); // ok
}

Regra prática muito importante


Em funções que só leem texto:
use &str

Porque aceita:

string literal
String

partes de strings
slices textuais

Isso deixa sua API melhor.

Correlação com Python


Em Python, você geralmente pensa:
“minha função recebe texto”

Em Rust, você deve pensar:


“minha função precisa possuir o texto?”
ou só precisa ler o texto?

Se só precisa ler, &str quase sempre é a escolha certa.

[Link] 25/46
09/03/2026, 14:52 Rust vs Python Strings

Exemplo com slice de string


Outra vantagem de &str é que ele representa não só uma string inteira, mas também um
pedaço de string.

fn main() {
let s = String::from("abcdef");
let parte: &str = &s[0..3];

println!("{}", parte);
}

Aqui parte vale "abc" .

Ou seja, &str é uma fatia textual.

Isso reforça a ideia:

String = dono do buffer

&str = visão sobre o texto inteiro ou parte dele

Comparando com Python: slicing


Em Python:

s = "abcdef"
parte = s[0:3]
print(parte)
Python Executar

Em Python, isso produz uma nova string.

Em Rust, &s[0..3] é uma fatia referenciada do texto, desde que respeite fronteiras UTF-8
válidas.

Esse detalhe é importante: Rust leva UTF-8 muito a sério.

Atenção importante: índices em string não são simples


Em Python, você acessa:

[Link] 26/46
09/03/2026, 14:52 Rust vs Python Strings

s = "abc"
print(s[0])
Python Executar

Em Rust, isso não é permitido diretamente para strings:

let s = String::from("abc");
// let c = s[0]; // erro
Rust

Porque strings em Rust são UTF-8, e um “caractere visual” pode ocupar mais de um byte.

Então Rust evita acesso ingênuo por índice.

Para iterar por caracteres:

fn main() {
let s = "áéí";

for c in [Link]() {
println!("{}", c);
}
}

Mais fundo: Deref<Target = str>


String implementa algo equivalente a:

Deref<Target = str>
Rust

Isso significa que uma referência para String pode ser tratada como referência para
str .

Você não precisa decorar a trait agora, mas precisa entender o efeito prático:

String “se comporta como” str quando emprestada.

[Link] 27/46
09/03/2026, 14:52 Rust vs Python Strings

Exemplo com método que pertence a str


Muitos métodos usados em String vêm, na prática, de str .

fn main() {
let s = String::from("rust");

println!("{}", [Link]());
println!("{}", [Link]("us"));
}

Isso funciona porque String pode ser vista como str .

Analogia boa para memorizar


Pense assim:

String é uma caixa dona do texto

str é o texto “visto por dentro”

&str é uma janela para olhar esse texto

Quando a função pede &str , ela está dizendo:

“não me importa quem é o dono; eu só quero enxergar o texto”

Isso é excelente design de API.

Exemplo comparando três abordagens


1. Ruim ou restrita demais

fn saudar(nome: &String) {
println!("Olá, {}", nome);
}
Rust

Aceita só &String .

2. Melhor
[Link] 28/46
09/03/2026, 14:52 Rust vs Python Strings

fn saudar(nome: &str) {
println!("Olá, {}", nome);
}
Rust

Aceita muito mais casos.

3. Quando precisa possuir

fn criar_saudacao(nome: &str) -> String {


format!("Olá, {}", nome)
}
Rust

Esse é um padrão extremamente idiomático.

Exemplo completo e idiomático

fn prefixar(prefixo: &str, valor: &str) -> String {


format!("{}{}", prefixo, valor)
}

fn main() {
let nome = String::from("Gandra");
let resultado = prefixar("Sr. ", &nome);

println!("{}", resultado);
}

Leitura didática
prefixo é &str

valor é &str

"Sr. " já é &str

&nome era &String , mas virou &str

o retorno é String , porque format! cria novo texto

[Link] 29/46
09/03/2026, 14:52 Rust vs Python Strings

O padrão mental certo


Guarde este fluxo:

Quando você tem um literal

let Rust
s = "abc"; // &str

Quando você constrói dinamicamente

let s = String::from("abc"); // String


Rust

Quando vai passar para função de leitura

funcao(&s);
Rust // &String -> &str

ou

funcao(s.as_str());
Rust

Erro comum de quem vem do Python


Quem vem de Python costuma pensar:

“Vou usar String em tudo, porque parece mais completo.”

Mas isso gera APIs desnecessariamente rígidas.

Em Rust, o pensamento mais maduro é:

entrada de leitura: &str


saída criada pela função: String

Resumo final desta etapa


[Link] 30/46
09/03/2026, 14:52 Rust vs Python Strings

String
possui o texto
pode crescer e ser modificado
aloca dinamicamente

str
é o tipo textual base
tem tamanho dinâmico
raramente aparece sozinho

&str
é referência para str
muito usado para leitura
flexível e idiomático

Deref coercion
permite que &String vire &str automaticamente em muitos contextos

Frase para decorar


A função pede &str porque quer ler texto, não porque quer saber quem é o dono dele.

Próximo passo natural


Agora o melhor próximo assunto é:

String , &String , str e &str lado a lado


com exemplos de:
memória
ownership
borrowing
parâmetros de função
retorno de função
erros comuns do compilador

Segue direto nessa trilha:

[Link] 31/46
09/03/2026, 14:52 Rust vs Python Strings

fn ler(texto: &str) {
println!("{}", texto);
}

fn criar() -> String {


String::from("novo texto")
}

fn main() {
let a: &str = "literal";
let b: String = String::from("dinâmico");

ler(a);
ler(&b);

let c = criar();
ler(&c);
}

Se quiser, no próximo passo eu monto uma tabela definitiva comparando String ,


&String , str e &str , que costuma eliminar de vez a confusão inicial.

sim, continue

Pensou por dois segundos

Perfeito. Agora vamos montar a tabela mental definitiva e depois eu vou te mostrar
quando cada um aparece no código real.

Visão geral
Os quatro nomes que mais confundem no começo são:

String
&String

str

&str

Mas eles não estão no mesmo nível.

O jeito certo de enxergar é este:

[Link] 32/46
09/03/2026, 14:52 Rust vs Python Strings

String = tipo dono do texto

str = tipo textual base, de tamanho dinâmico

&str = referência para texto

&String = referência para uma String

Tabela definitiva
É dono do Tem tamanho Usado
Tipo texto? conhecido? sozinho? Uso real

String sim sim sim texto dinâmico, mutável

&String não sim sim empréstimo de String ,


menos comum em APIs

str não no sentido não quase nunca tipo base textual


prático de uso
direto

&str não sim sim leitura de texto, fatias,


literais

1. String
O que é
String é o tipo que possui o texto.

Exemplo:

fn main() {
let nome: String = String::from("Gandra");
println!("{}", nome);
}
Rust

O que ela guarda


Conceitualmente, String guarda algo como:
ponteiro para os bytes

[Link] 33/46
09/03/2026, 14:52 Rust vs Python Strings

tamanho atual
capacidade

Ou seja, ela é uma estrutura de tamanho fixo que administra um buffer de tamanho
variável na heap.

Comparação com Python


Isso lembra um pouco a ideia de um objeto Python que encapsula dados, mas em Rust a
posse é explícita.

2. &String
O que é
&String é uma referência para uma String .

Exemplo:

fn main() {
let nome = String::from("Gandra");
let referencia: &String = &nome;

println!("{}", referencia);
}

Por que existe?


Porque às vezes você empresta uma String .

Mas aqui está o ponto importante:

Em APIs, quase sempre &str é melhor que &String .

Porque &String é mais específico do que precisa.

3. str
O que é
str é o tipo textual base.

[Link] 34/46
09/03/2026, 14:52 Rust vs Python Strings

Mas ele é um tipo de tamanho dinâmico.


Então quase nunca aparece sozinho.

Isso não é comum:

let Rust
x: str = ...;

Porque str sozinho não cabe no modelo normal de variável local comum.

4. &str
O que é
&str é uma referência para um texto.

Ele aponta para:

uma string literal


uma fatia de String
uma fatia de outro &str

Exemplo:

fn main() {
let s: &str = "Olá";
println!("{}", s);
}
Rust
Esse é o tipo mais comum para ler texto.

Hierarquia mental correta


Essa parte é muito importante.

Não pense assim


“ String e str são a mesma coisa, um com & e outro sem.”

Isso está errado.

[Link] 35/46
09/03/2026, 14:52 Rust vs Python Strings

Pense assim
str é o tipo textual fundamental

&str é referência para esse tipo textual

String é um container dono que armazena texto


&String é referência para esse container

Desenho mental simples


Imagine isto:

String
Rust

é uma caixa dona.

Dentro dela existe texto que pode ser visto como:

str Rust

Quando você empresta esse conteúdo textual, obtém:

&strRust

Quando você empresta a caixa inteira, obtém:

&String
Rust

Exemplo lado a lado

fn mostrar(texto: &str) {
println!("{}", texto);
}

[Link] 36/46
09/03/2026, 14:52 Rust vs Python Strings

fn main() {
let a: &str = "literal";
let b: String = String::from("dinâmico");
let c: &String = &b;
let d: &str = &b;

mostrar(a);
mostrar(c);
mostrar(d);
}

O que acontece aqui?


a já é &str

b é String

c é &String

d é &str , obtido a partir de b

E mostrar(c) funciona porque Rust consegue converter &String em &str .

Por que &String é menos usado?


Porque ele aceita menos coisas.

Veja:

fn exibir(texto: &String) {
println!("{}", texto);
}
Rust

Essa função aceita isto:

let s = String::from("abc");
exibir(&s);
Rust

Mas não aceita isto:

exibir("abc");
Rust

[Link] 37/46
09/03/2026, 14:52 Rust vs Python Strings

Agora compare com:

fn exibir(texto: &str) {
println!("{}", texto);
}
Rust

Essa aceita:

let s = String::from("abc");
exibir(&s);
exibir("abc");
Rust

Então &str é melhor para funções que só querem ler texto.

Regra prática excelente


Use &str quando:
a função só precisa ler texto
você quer aceitar literais e String
quer uma API mais flexível

Use String quando:


a função precisa ser dona do texto
você vai construir, modificar ou retornar texto

Evite &String como parâmetro, salvo caso muito específico

Exemplo com função ruim e função boa


Menos idiomático

fn saudacao(nome: &String) {
println!("Olá, {}", nome);
}
Rust

[Link] 38/46
09/03/2026, 14:52 Rust vs Python Strings

Mais idiomático

fn saudacao(nome: &str) {
println!("Olá, {}", nome);
}
Rust

A segunda é melhor porque aceita mais casos sem custo extra desnecessário.

Comparação com Python


Em Python, você faria:

def saudacao(nome: str):


print(f"Olá, {nome}")
Python Executar

E tanto faz se a origem veio de literal, concatenação, arquivo etc.

Em Rust, o equivalente mais flexível a esse “recebo qualquer texto para leitura” é:

fn saudacao(nome:
Rust &str)

Quando aparece str no mundo real?


Você raramente escreve str sozinho, mas ele aparece indiretamente o tempo todo.

Por exemplo:

let Rust
s: &str = "abc";

Aqui o tipo real referenciado é str .

Outro exemplo:

[Link] 39/46
09/03/2026, 14:52 Rust vs Python Strings

let Rust
parte = &texto[0..3];

Esse parte é um &str .

Ou seja, str está sempre ali como tipo base, mas quase sempre atrás de referência.

Quando aparece &String no mundo real?


Menos do que iniciantes imaginam.

Pode aparecer:

em código escrito de forma não idiomática


quando alguém ainda não generalizou a API
em alguns contextos internos ou temporários

Mas em código bom, função de leitura geralmente recebe &str , não &String .

Quando aparece String no mundo real?


O tempo todo, quando você:
lê entrada do usuário
monta texto com format!
concatena
armazena nomes, caminhos, conteúdo carregado
retorna novo texto

Exemplo:

fn criar_mensagem(nome: &str) -> String {


format!("Bem-vindo, {}", nome)
}
Rust

Isso é muito comum e muito idiomático.

Um detalhe importante sobre mutação


String pode ser alterada
[Link] 40/46
09/03/2026, 14:52 Rust vs Python Strings

fn main() {
let mut s = String::from("Olá");
s.push_str(" mundo");
println!("{}", s);
}
R t

&str não é buffer mutável

fn main() {
let s: &str = "Olá";
println!("{}", s);
}
Rust
&str é só uma visão para leitura do texto.

Outro ponto que confunde: &mut str


Existe, mas é raro no uso cotidiano.

Você vai ver muito mais:

&str

String

&mut String

Por exemplo:

fn append_world(s: &mut String) {


s.push_str(" world");
}
Rust

Aqui faz sentido usar &mut String , porque você quer modificar a string dona.

Tabela de uso prático

[Link] 41/46
09/03/2026, 14:52 Rust vs Python Strings

Situação Tipo ideal

literal textual &str

ler texto em parâmetro &str

retornar texto novo String

armazenar texto dinâmico String

modificar texto existente &mut String

emprestar uma String sem mutar normalmente converter para &str

Exemplos reais de assinatura


Ler apenas

fn validar_email(email:
Rust &str) -> bool

Criar novo texto

fn normalizar_nome(nome: &str) -> String


Rust

Modificar texto existente

fn adicionar_prefixo(s: &mut String)


Rust

Receber posse

fn consumir_texto(s: String)
Rust

Esse último só faz sentido se a função realmente precisa ficar com a posse.

[Link] 42/46
09/03/2026, 14:52 Rust vs Python Strings

Exemplo completo com os quatro conceitos

fn ler(texto: &str) {
println!("Lendo: {}", texto);
}

fn criar() -> String {


String::from("texto criado")
}

fn alterar(texto: &mut String) {


texto.push_str(" alterado");
}

fn main() {
let literal: &str = "olá";
let mut dono: String = String::from("rust");
let referencia_string: &String = &dono;
let referencia_texto: &str = &dono;

ler(literal);
ler(referencia_string);
ler(referencia_texto);

alterar(&mut dono);

let novo = criar();


ler(&novo);
}

Leitura didática linha por linha


literal: &str = "olá";
Literal textual vira &str .

dono: String = String::from("rust");


Aqui temos uma string dinâmica, dona do conteúdo.

referencia_string: &String = &dono;


Isso é referência para a String inteira.

referencia_texto: &str = &dono;

[Link] 43/46
09/03/2026, 14:52 Rust vs Python Strings

Aqui estamos pegando uma visão textual da String .

ler(referencia_string);
Funciona porque Rust converte &String para &str .

alterar(&mut dono);
Agora estamos emprestando a String com mutabilidade.

let novo = criar();


A função devolve posse de um texto recém-criado.

O erro mental mais comum de quem vem de Python


É este:

“Se eu tenho um texto dinâmico, então devo passar &String para funções.”

Não.
Quase sempre a função não quer saber se você tem uma String , um literal ou uma fatia.
Ela quer só ler texto.

Então o tipo mais apropriado geralmente é &str .

Mapa mental definitivo


Guarde assim:

String
“Eu sou dono do texto.”

&String
“Eu emprestei a caixa que é dona do texto.”

str
“Eu sou o texto base, mas meu tamanho não é fixo.”

&str
“Eu sou uma visão emprestada do texto.”

[Link] 44/46
09/03/2026, 14:52 Rust vs Python Strings

Frase mais importante desta etapa


&str fala sobre o conteúdo textual; &String fala sobre a estrutura dona desse

conteúdo.

Na maioria das APIs, o que importa é o conteúdo textual.


Por isso &str vence quase sempre.

Exercício mental rápido


Diga qual tipo você usaria:

1. Função que só imprime um nome


Resposta: &str

2. Função que monta uma mensagem nova


Resposta: recebe &str , retorna String

3. Função que acrescenta sufixo no mesmo buffer


Resposta: &mut String

4. Variável com texto vindo de format!


Resposta: String

Exemplo idiomático final

Rust

fn slugify(texto: &str) -> String {


[Link]().to_lowercase().replace(' ', "-")
}

fn main() {
let titulo = Strin

[Link] 45/46
09/03/2026, 14:52 Rust vs Python Strings

[Link] 46/46

Você também pode gostar