當參數是引用類型並且是以傳值的方式傳入參數的時候,方法傳入的是這個對象的引用的一個副本,相當於是以一個引用的值按照傳值的方式調用方法。這個引用在方法內部會生成一個副本,就像普通的值類型變量一樣,但是由於這個引用的副本和原來方法外面的類型的引用是指向了同一個對象,所以方法內部對這個對象進行的各種操作(改變對象的屬性等)看上去就像是按引用傳遞變量了,返回之後對象會發生變化。但是如果在方法內部對這個引用的副本進行了賦值操作,那麼這個引用的副本就不再指向原來的對象了,方法返回後,原來的對象自然也不會發生變化。
Python解析:
# -*- coding:utf-8 -*- lst = [1, 2, 3] def func1(lst): lst.append(4) def func2(lst): lst = lst[:-1] # 賦值操作,lst不再指向原來的對象了 print(lst) func1(lst) print(lst) # lst = [1, 2, 3, 4], 函數內改變lst的屬性,同樣反應到了函數外的lst變量 func2(lst) print(lst) # lst = [1, 2, 3],
結論:在函數的調用中,傳入引用類型做參數的時候,它仍然是以值傳遞的方式傳遞參數的,只不過傳入方法內部的是對象的引用的值。同樣的,C#和Java也有相同過的問題。C#可以增加ref關鍵字來解決這個問題。