2013-03-17 19 views
5

Sono nuovo di Ruby e di questo sito.Differenza tra operatori di stringa + e << in Ruby

Le seguenti due funzioni sono diverse, una modifica la variabile all'esterno della funzione e l'altra no.

def m1 (x) 
    x << "4" 
end 

def m2 (x) 
    x = x + "4" 
end 


str="123" 

m2(str) #str remains unchanged 123 

m1(str) #str is changed to 1234 

vorrei assicurarsi che ho capito bene -

Quando M1 si chiama, il riferimento al str viene copiato e passato alla funzione, che vede come x. Operatore < < modifiche x che fa riferimento allo str str originale viene modificato da questa operazione.

Quando viene chiamato m2, il riferimento a str viene copiato e passato alla funzione che lo vede come x. Operatore + crea una nuova stringa e l'assegnazione x = x + "4" semplicemente reindirizza x alla nuova stringa lasciando intatta la variabile str originale.

Giusto?

Grazie

method declarations and invokation

+0

'm2 (str)' deve restituire '" 1234 "', quindi 'm1 (str)' deve restituire '" 1234 "' e dopo che 'str' sarà uguale a' "1234" '. Sei sicuro dei tuoi risultati? – mraaroncruz

+1

sto usando 'Ruby 1.9.3p392' e funziona nel mio caso. metti 'puts' prima di quei metodi e controlla. – Davit

+0

@tmpmember cosa intendi con "funziona" nel tuo caso? – mraaroncruz

risposta

10

String#+ :: str + other_str → new_str concatenazione-Restituisce una nuova stringa contenente other_str concatenato a str.

String#<< :: str << integer → str: Aggiungi-Concatena l'oggetto dato a str.

<< non crea il nuovo oggetto, in cui come + fa.

a = "str" 
#=> "str" 
a.object_id 
#=> 14469636 
b = a << "ing" 
#=> "string" 
a.object_id 
#=> 14469636 
b.object_id 
#=> 14469636 

a= "str" 
#=> "str" 
b = a + "ing" 
#=> "string" 
a.object_id 
#=> 16666584 
b.object_id 
#=> 17528916 

EDIT

Dal tuo commento, ha ottenuto il punto. Vedere di seguito:

def m1 (x) 
x << "4" 
end 
#=> nil 
def m2 (x) 
x = x + "4" 
end 
#=> nil 

str="123" 
#=> "123" 

m2(str) 
#=> "1234" 

str 
#=> "123" 

Qui str non cambiava come hai superato il valore all'interno del metodo m2(), tutte le modifiche locali al metodo secondo la chiamata di cui sopra. Pertanto, sotto str non viene mostrata la modifica. Per visualizzare la modifica, è necessario chiamarla come di seguito.

str = m2(str) 
#=> "1234" 

str 
#=> "1234" 

O

Si potrebbe fare le cose, come di seguito: - dove ho passato l'indirizzo di riferimento di str ma non il valore.

str = "abc" 
#=> "abc" 
str.object_id 
#=> 16250484 
ObjectSpace._id2ref(16250484) 
#=> "abc" 
def m1 (x) 
ObjectSpace._id2ref(x) << "4" 
end 
#=> nil 
m1(16250484) 
#=> "abc4" 
str 
#=> "abc4" 

Speranza ha senso :)

Cheers!

+0

grazie mille per il vostro aiuto – yonso

+0

Vedere il mio 'EDIT', Spero che aiuti. –

+0

sì grazie mille, questo esempio di codice apparentemente "innocente" in realtà ha molto dietro, come mi hai aiutato a vedere :) – yonso

2

<< l'operatore di concatenazione è distruttivo per una stringa.Ciò significa che manipolerà la variabile su cui agisce, non solo restituirà il risultato dell'espressione.

esempio:

str = "abc" 
puts str + "d" # "abcd" 

puts str # "abc" 

puts str << "d" # "abcd" 

puts str # "abcd" 
+0

grazie mille per il tuo aiuto – yonso

1

le due seguenti funzioni sono diverse, si altera la variabile di fuori della funzione e uno non lo fa.

Questo è sbagliato. dei due metodi (sono metodi, BTW, non funzioni, Ruby non ha funzioni, c'è una differenza fondamentale) altera la variabile str. m1 modifica l'oggetto la variabile punti a, ma ciò è completamente diverso dalla modifica della variabile stessa.

+0

sì hai ragione, questo è qualcosa che ho capito solo dopo – yonso

Problemi correlati