通过telegram 传递变量_浅析参数传递

本文探讨了编程语言如Java、Python和Go中的参数传递方式,包括值传递和引用传递的特点。值传递复制变量内容,不改变原始变量;引用传递则共享同一内存空间,函数内修改会影响外部变量。Java中基本类型为值传递,对象为引用传递;Go中非指针类型为值传递,指针为引用传递;Python中不可变对象为值传递,可变对象为引用传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在使用了多种语言之后,发现不同语言之间,参数传递的方式有很多细微的差异,一不小心就会在这方面踩坑,今天我们就来聊一聊java,python和go语言中具体的参数传递方式和其特点。

首先来了解一下编程语言中参数传递有哪些方式

1.值传递2.引用传递

什么是值传递?什么是引用传递?

值传递:将原变量内容复制下来,再用一个新的内存空间来保存,两个变量之间相互独立; 函数范围内对值的任何改变在函数外部都会被忽略, 系统将为目标对象重新开辟一个完全相同的内存空间;

引用传递:给当前变量起了一个别名,实际上这两个变量引用的是一个值。相当于给一个变量起了两个名字;函数范围内对值的任何改变在函数外部也能反映出这些修改, 它们指向同一内存空间;

其实,无论是值传递还是引用传递,传递给函数的都是变量的副本,不同的是值传递的是值的拷贝,引用传递的是地址的拷贝,地址拷贝效率高,因为数据量小,而值拷贝决定于数据量的大小,数据越大,效率越低

值传递和引用传递

下面使用一个示例来演示一下值传递

1.java示例

public class test {        public static void main(String[] args) {            int n = 3;            System.out.println("Before change, n = " + n);            change(n);            System.out.println("After change(n), n = " + n);        }        public static void change(int nn) {            nn = 10;        }}
// resultBefore change, n = 3After change(n), n = 3 

1.go示例

type example struct {  s string}func main() {  ns := example{s: "hello"}  fmt.Printf("before change %v, ptr:%p\n", ns, &ns)  change(ns)  fmt.Printf("after change %v, ptr:%p\n", ns, &ns)}func change(example example) {  example.s = "hello world"  fmt.Printf("changing %v, ptr:%p\n", example, &example)}
// resultbefore change {hello}, ptr:0xc000010200changing {hello world}, ptr:0xc000010220after change {hello}, ptr:0xc000010200

1.python2.7示例

def change(a):    a = 20if __name__ == "__main__":    a = 10    print("before change, "+str(a))    change(a)    print("after change, "+str(a))
# resultbefore change, 10after change, 10

上面3个例子可以发现,都使用的是值传递,change方法执行后并不会影响外部的原始变量

效果如图

2a947a7e20c59c078e4bae6b25f5b5c7.png

总结一下

•java,在基本类型为(byte,short,int,long,double,float,char,boolean)时为值传递•go,在类型为非指针的任意类型里,都是使用的值传递•python,在类型为不可变对象(比如str,int或者tuple),不能直接修改原始对象——相当于通过“传值”来传递对象

那么哪些时候使用的是引用传递呢?

1.java示例

public class test2 {    public static void main(String[] args) {        StringBuffer sb = new StringBuffer("Hello ");        System.out.println("Before change, sb = " + sb);        change(sb);        System.out.println("After change(n), sb = " + sb);    }    public static void change(StringBuffer strBuf) {        strBuf.append("World!");    }}
// resultBefore change, sb = Hello After change(n), sb = Hello World!

1.go示例

func main(){  s := "hello"  fmt.Printf("before change %s, ptr:%p\n",s, &s)  change(&s)  fmt.Printf("after change %s, ptr:%p\n",s, &s)}func change(s *string) {  *s = *s + " world"  fmt.Printf("changing %s, ptr:%p\n",*s, s)}
// resultbefore change hello, ptr:0xc00003a1f0changing hello world,ptr:0xc00003a1f0after change hello world, ptr:0xc00003a1f0

‍‍1.python2.7示例

def change(l):    l.append("world")if __name__ == "__main__":    l = ["hello"]    print("before change, ", l)    change(l)    print("after change, ",l)
# result('before change, ', ['hello'])('after change, ', ['hello', 'world'])

示例发现,执行change方法后,外部的变量也发生的改变,所以使用的是引用传递

效果如图

a20787c6d6710ddb1971e7abe47e7b27.png

总结

•java,对象类型(Object,数组,容器)均为引用传递•go,当类型为指针时,为引用传递•python,当为可变对象(map, list)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。

java和python传递场景类型,基础类型使用值传递,对象使用引用传递;go传递方式与类型无关,只与是否是指针有关

值传递和引用传递特点

值传递

1.必须复制值,特别时对于大型的字符串和对象来说,将会是一个代价很大的操作2.复制的新值和原始变量相互独立,互不影响3.值传递使用的基础类型一般都分配在栈空间中,不需要gc,提升性能

引用传递

1.引用传递不用复制值,对性能提高很有好处2.引用传递的对象或者指针一般分配到堆内存中,当频繁创建销毁,gc会大大降低性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值