先玩个小游戏: 三段代码,分别是C、C++、Golang,猜输出结果
先看C
#include <stdio.h>
struct Simple {
int Number;
};
void SetF(struct Simple *s){
printf("SetF---------%d\n", s->Number);
struct Simple s_v2;
s_v2.Number=1;
s = &s_v2;
printf("SetF---------%d\n", s->Number);
}
void SetF2(struct Simple *s){
printf("SetF2---------%d\n", s->Number);
struct Simple s_v2;
s_v2.Number=2;
*s = s_v2;
printf("SetF2---------%d\n", s->Number);
}
int main()
{
struct Simple testS;
printf("Simple=%d\n", testS.Number);
SetF(&testS);
printf("SetF=%d\n", testS.Number);
SetF2(&testS);
printf("SetF2=%d\n", testS.Number);
return 0;
}
结果如下:
Simple=0
SetF---------0
SetF---------1
SetF=0
SetF2---------0
SetF2---------2
SetF2=2
猜对了吗?
继续看C++
#include <iostream>
using namespace std;
struct Simple {
int Number;
};
void SetF(struct Simple &s){
printf("SetF---------%d\n", s.Number);
s.Number=1;
printf("SetF---------%d\n", s.Number);
}
void SetF2(struct Simple &s){
printf("SetF2---------%d\n", s.Number);
struct Simple s_v2;
s_v2.Number=2;
s = s_v2;
printf("SetF2---------%d\n", s.Number);
}
int main()
{
struct Simple s;
s.Number=0;
printf("Simple=%d\n", s.Number);
SetF(s);
printf("Simple=%d\n", s.Number);
SetF2(s);
printf("Simple=%d\n", s.Number);
return 0;
}
运行结果如下:
Simple=0
SetF---------0
SetF---------1
Simple=1
SetF2---------1
SetF2---------2
Simple=2
猜到了吗?
最后看看GO
package main
import (
"fmt"
"testing"
)
type Simple struct {
number int
}
func SetF(s *Simple) {
s = &Simple{
number: 1,
}
}
func SetF2(s *Simple) {
*s = Simple{
number: 2,
}
}
func SetF3(s *Simple) {
s.number = 3
}
func Test1(t *testing.T) {
var testS *Simple
SetF(testS)
fmt.Printf("type of c:%T\n", testS)
fmt.Printf("value of c:%v\n", testS)
}
func Test1_1(t *testing.T) {
var testS Simple
SetF(&testS)
fmt.Printf("type of c:%T\n", testS)
fmt.Printf("value of c:%v\n", testS)
}
func Test2(t *testing.T) {
var testS *Simple
SetF2(testS)
fmt.Printf("type of c:%T\n", testS)
fmt.Printf("value of c:%v\n", testS)
}
func Test2_1(t *testing.T) {
var testS Simple
SetF2(&testS)
fmt.Printf("type of c:%T\n", testS)
fmt.Printf("value of c:%v\n", testS)
}
func Test3(t *testing.T) {
var testS *Simple
SetF3(testS)
fmt.Printf("type of c:%T\n", testS)
fmt.Printf("value of c:%v\n", testS)
}
func Test3_1(t *testing.T) {
var testS Simple
SetF3(&testS)
fmt.Printf("type of c:%T\n", testS)
fmt.Printf("value of c:%v\n", testS)
}
运行结果:
1:
type of c:*main.Simple
value of c:<nil>
1-2:
type of c:main.Simple
value of c:{0}
2:
panic: runtime error: invalid memory address or nil pointer dereference
2-1:
type of c:main.Simple
value of c:{2}
3:
panic: runtime error: invalid memory address or nil pointer dereference
3-1:
type of c:main.Simple
value of c:{3}
请在评论区留下你的成绩
从上面的几段代码中可以看出:
Golang 和 C 一脉相承,均没有引用传递,所有传递均为值传递。
package unsafe
type ArbitraryType int
type Pointer *ArbitraryType
看源码,Go的指针,其实就是int值。
所以子函数拿到的都是一个地址
- 修改这个地址本身没有任何意义
- 修改这个地址指向的内容才有意义
- 指向的内容如果是nil,会panic