Python 的参数传递是赋值传递 (pass by assignment),或者叫作对象的引用传递(pass by object reference)。Python 里所有的数据类型都是对象,所以参数传递时,只是让新变量与原变量指向相同的对象而已,并不存在值传递或是引用传递一说。 ----来自互联网
总结一下:就是在使用函数时,把实参赋给函数的形参,即形参=实参,函数的形参和实参指向同一对象。
那么在函数中参数的变化只受其本身对象的性质影响了。
Python中的数据类型有可变不可变,string这种不可变类型被修改后相当于重新赋值,句柄指向新的对象。
传递string(不可变)
def fun(a:str):
    print("2  ",id(a))
    a+="b"
    print("3   ",id(a))
a="aa"
print(id(a))
fun(a)
print(a)
1753958904624 
2   1753958904624    #传递前后是一个对象
3    1753960317104   #string是不可变类型,修改了就是另一个对象
aa 
传递list(可变类型)
def fun(a:list):
    print("2  ",id(a))
    a.append("1")
    print("3   ",id(a))
a=[‘a‘,‘b‘]
print(id(a))
fun(a)
print(a)
2017284788416         #传递前后是一个对象
2   2017284788416
3    2017284788416   #list是可变类型,即使修改了,对象也没变
[‘a‘, ‘b‘, ‘1‘]      
JS和Python一样,也是直接把实参给了形参。
string(不可变的值类型)
function f(str) {
    console.log("内部:  ",str==="Hello World");
    str += "!";
    return str;
}
var str="Hello World";
console.log("外部1: ",str==="Hello World");
console.log("外部2:   ",str===f(str));
外部1:  true
内部:   true
外部2:    false
Array(引用类型)
function f(arr2) {
   console.log(arr===arr2);
   arr2.push("!");
   console.log(arr===arr2);
}
var arr=[];
arr.push("hello");
arr.push("world");
f(arr);
console.log("数组: ",arr);
true
true
数组:  [ ‘hello‘, ‘world‘, ‘!‘ ]
Java的数据类型分为两种:基本类型和引用类型。
引用类型分为下面几种:类类型(class,interface,enum,annotation)和数组类型 。
Java也是赋值传递。
int(基本类型)
基本类型不需要new,赋值直接使用,修改了句柄就指向新的位置了。
public class Args_ref {
    public static int f(int x){
        x+=1;
        return x;
    }
    
    public static void main(String[] args) {
        int x=10;
        int y=f(x);
        System.out.printf("x=%d, y=%d, x==y?%b",x,y,x==y);
    }
    
}
x=10, y=11, x==y?false
数组(对象)
数组是对象。
 	public static int[] ff(int[] x){
        System.out.println("ff hashCode: "+x.hashCode());
        if(x!=null){
            x[0]=100;    //修改一下x中的元素,也就是对原数组进行修改
        }
        return x;
    }
	public static void main(String[] args) {
        int[] s={1,2,3,4};
    
        System.out.println("main hashCode: "+s.hashCode());
        System.out.println("main ff hashCode: "+ff(s).hashCode());
        for(int i:s){
            System.out.println(i);
        }
}
main hashCode: 366712642  //数组传递前后,修改前后都没有变化
ff hashCode: 366712642  
main ff hashCode: 366712642 
100                
2
3
4
String(对象、不可变)
Java中String是对象类型,但也是不可变的,修改也是重新赋值,句柄指向新的字面量。
public static String ss(String s){
        System.out.println("ss1: "+s.hashCode());
        s+="nice";
        System.out.println("ss2: "+s.hashCode());
        return s;
    }
    public static void main(String[] args) {
        String s="Hello Java";
        System.out.println("main1: "+s.hashCode());
        
        System.out.println("main2: "+ss(s).hashCode());
        System.out.println(s);
    }
main1: 387417328   //传递前后没有变化
ss1: 387417328
ss2: 85926989       //修改后hashCode不一样了
main2: 85926989
Hello Java
Go语言和C一样,是传值的,就是把实参拷贝一份给形参,不管你是值类型还是引用类型。
Go语言不同于Python\Java,因为它提供了指针,可以通过传递指针,达到上面那些语言的功能。
Go中就通过指针模拟面向对象的this关键字
String(值类型)
Go中的String是值类型,
//值类型是拷贝
func f(data string){
	fmt.Printf("data:  %p\n",&data)
	data+="hi"
}
func main()  {
	var s string="ok"
	fmt.Printf("s    :  %p\n",&s)
	f(s)
	fmt.Println("s    :  "+s)
}
s    :  0xc0000421f0  
data:  0xc000042200  //地址不一样,拷贝了一份新的
s    :  ok          
[]string切片
func a(data []string)  {
	fmt.Printf("data1:  %p\n",&data)
	adata:=append(data,"!")      //生成了新切片,从append函数也可以看出是拷贝了,否则没必要返回一个新切片
    							//func append(slice []Type, elems ...Type) []Type
	fmt.Printf("data2:  %p,%s\n",&data,data)
	fmt.Printf("adata:  %p,%s\n",&adata,adata)
}
func main()  {
	var scl []string=[]string{"Hi ","My ","Friend "}
	fmt.Printf("scl:  %p\n",&scl)
	a(scl)  //把实参拷贝一份给形参,互不影响
	fmt.Println(scl) 
}
scl:  0xc000004480
data1:  0xc0000044c0     //拷贝到新的内存里      
data2:  0xc0000044c0,[Hi  My  Friend ]
adata:  0xc0000044e0,[Hi  My  Friend  !] 
[Hi  My  Friend ]    
[]string(切片指针)
把地址作值传进去,这时形参修改也会影响到实参了。
Go中模拟面向对象时,用这个特性模拟this关键字。
func a(data *[]string)  { 
	fmt.Printf("data1:  %p\n",data)
	if len(*data)>=0{
		(*data)[0]="nono"   //这里修改就会影响到外界
	}
}
func main()  {
	var scl *[]string=&[]string{"Hi ","My ","Friend "}
	fmt.Printf("scl:  %p\n",scl)
	a(scl)
	fmt.Println(scl)
}
scl:  0xc000068440     //地址相同
data1:  0xc000068440
&[nono My  Friend ]    //函数影响到了外界
原文:https://www.cnblogs.com/cgl-dong/p/14060762.html