return 返回具体类型和interface{}时遇到的问题

zhaozonglu · · 820 次点击
####你这个问题其实包含两个问题: 1.其实你的第二段代码并非你所写的情况,编译器识别的testDemo函数应该是 ···func testDemo() (interface{}, int) { var a int return interface{}(a), change(&a) }··· 只不过你写代码时省略了 interface{}(a)这个转化过程,但是编译器会帮你补上(暂时这么理解,其实是运行时执行的),这样它按照从左到右的顺序执行返回值,会先执行 interface{}(a),再执行change函数,然后赋值给return。 而你的第一段代码中并不需要执行 interface{}(a),所以会先执行change函数,然后赋值给return。 2.你的第一个返回值都不是传指针类型,所以不存在后执行的change函数给已存在的变量a重新赋值的问题。 具体证明你可以打开debug模式,单行调试,涉及interface{}参数或返回值(你的程序中两处:打印和testDemo)的地方,你会发现调用了runtime包下iface.go里的转化代码,涉及本代码二使用的是runtime.convT2E64(注释:`// The convXXX functions are guaranteed by the compiler to succeed.`说明此函数由编译器保证其正常执行)此时你再看作为值得elem参数,其存储之地址和调用前a的地址已经不一致,说明已经发生过数据拷贝,再结合266-267行```x = mallocgc(8, t, false) *(*uint64)(x) = *(*uint64)(elem)```又申请一块新内存(uint64),可知虽然你的change返回地址,却因为编译器的原因已不可能越过以上代码返回到testDemo外层。
#1