1 new
C++: 使用new 会返回一个TreeNode类型的指针,并调用其构造函数来初始化对象。需要手动使用delete来释放内存。
TreeNode* node = new TreeNode()
GO:返回的也是一个指针,不过用法不一样。用于动态分配内存空间,并返回一个指向该类型零值的指针。不需要使用delete操作符来释放内存
var node *TreeNode = new(TreeNode)
2 自动类型推导
C++: 使用auto
auto node = new TreeNode()
GO: 使用 :=
node:= new(TreeNode)
3 函数
函数声明和定义的语法不同:GO 函数定义使用关键字 func,而 C++ 函数定义使用返回类型及函数名。
C++:
int add(int a, int b) {
return a + b;
}
GO:
func add(a, b int) int {
return a + b
}
GO函数多返回值示例:
C++:
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
GO:
func swap(a, b int) (int, int) {
//func函数关键字 | 函数名| 函数参数| 函数返回值类型|
return b, a
}
4指针
GO语言不支持指针的自增自减操作。这是因为在GO语言中,指针的使用相对比较严格,GO语言的设计者认为指针的自增自减操作容易引起混淆和错误,因此取消了这个操作符。
func test(){
var numbers [2]int
numbers[0] = 100
numbers[1] = 200
p := &numbers[0]
fmt.Printf("p: %p,*p: %d\n", p, *p) //p=0xc0000180e0,*p=100
p += 1 //报错 (mismatched types *int and untyped int) ,地址不能+1,因为go里面指针不能自增自减
fmt.Printf("p: %p,*p: %d\n", p, *p)
}
但是也有办法实现C++里面的操作,但是非常麻烦,需要导入 unsafe包。操作如下
import "unsafe"
var i int = 100
p := &i
p = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(1))) //类似C++里面的 p++
fmt.Printf("p: %v\n", p) //这里地址会+1
进一步我们可以实现以下这个操作来实现指针操作数组:
func test() {
var numbers [2]int
numbers[0] = 100
numbers[1] = 200
p := &numbers[0]
fmt.Printf("p: %p,*p: %d\n", p, *p)
fmt.Printf("&numbers[1]: %p,numbers[1]: %d\n", &numbers[1], numbers[1])
size := unsafe.Sizeof(numbers[1])
fmt.Printf("int size: %d bytes\n", size)
p = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(8))) //uintptr(1)是一个byte大小
fmt.Printf("p: %p,*p: %d\n", p, *p)
}
输出如下:
p: 0xc0000180e0,*p: 100
&numbers[1]: 0xc0000180e8,numbers[1]: 200
int size: 8 bytes
p: 0xc0000180e8,*p: 200
总之比较复杂,尽量在go里面尽量避免指针加加减减。
5 结构体
在GO语言中,如果标识符(例如类型名、变量名、函数名等)的首字母是大写字母,那么它就是导出的(Exported),可以被其他包(Package)访问和使用。如果标识符的首字母是小写字母,则它是未导出的(Unexported),只能在当前包内访问和使用。即使结构体类型是导出的,结构体的成员变量如果首字母是小写字母,也是未导出的,只能在结构体定义所在的包内访问和使用。
// 导出的结构体类型
type Person struct {
Name string
Age int
}
// 未导出的结构体类型
type person struct {
name string
age int
}
在C++语言中,结构体可以定义成员函数,使用成员函数来操作结构体的成员变量。而在GO语言中,结构体可以定义方法(Method),使用方法来操作结构体的成员变量。方法定义需要在方法名前指定接收者类型,可以是值类型或指针类型。例如:
struct Person {
// ... C++
void setAge(int age) {
this->age = age;
}
};
type Person struct { //GO
name string
age int
}
func (p *Person) SetAge(age int) {
p.age = age
}
GO绑定函数里面的第一个括号表示要绑定的结构体是Person,p是一个类似C++里面的this,通过p可以访问Person里面变量