Aqui está uma boa maneira de pensar sobre a diferença entre tipos de valor, passagem por valor, tipos de referência e passagem por referência:
Uma variável é um contêiner.
Uma variável do tipo valor contém uma instância. Uma variável do tipo de referência contém um ponteiro para uma instância armazenada em outro local.
A modificação de uma variável do tipo valor muda a instância que ela contém. A modificação de uma variável do tipo de referência altera a instância para a qual ela aponta.
Variáveis de tipo de referência separadas podem apontar para a mesma instância. Portanto, a mesma instância pode ser modificada por qualquer variável que aponte para ela.
Um argumento passado por valor é um novo contêiner com uma nova cópia do conteúdo. Um argumento passado por referência é o contêiner original com seu conteúdo original.
Quando um argumento do tipo valor é passado por valor: A reatribuição do conteúdo do argumento não tem efeito fora do escopo, porque o contêiner é exclusivo. A modificação do argumento não tem efeito fora do escopo, porque a instância é uma cópia independente.
Quando um argumento do tipo de referência é passado por valor: A reatribuição do conteúdo do argumento não tem efeito fora do escopo, porque o contêiner é exclusivo. A modificação do conteúdo do argumento afeta o escopo externo, porque o ponteiro copiado aponta para uma instância compartilhada.
Quando qualquer argumento é passado por referência: A reatribuição do conteúdo do argumento afeta o escopo externo, porque o contêiner é compartilhado. A modificação do conteúdo do argumento afeta o escopo externo, porque o conteúdo é compartilhado.
Em conclusão:
Uma variável de sequência é uma variável do tipo de referência. Portanto, ele contém um ponteiro para uma instância armazenada em outro local. Quando passado por valor, seu ponteiro é copiado, portanto, a modificação de um argumento de string deve afetar a instância compartilhada. No entanto, uma instância de string não possui propriedades mutáveis, portanto, um argumento de string não pode ser modificado de qualquer maneira. Quando passado por referência, o contêiner do ponteiro é compartilhado, portanto, a reatribuição ainda afetará o escopo externo.