java转go的多少踩了坑,刚开始代码都是一堆java的思想来学习go,这个似乎是不对的,虽说语言都互有通性,但是无论是之前是学啥语言的然后来接触go的,我想刚开始都会踩到一些坑的,当然这多数是个人的看法,也许是自身的无知,毕竟隔几个月再去看以前的代码也是一脸懵逼得。以下还是来看看我踩到的坑吧。
1. 理解指针
不说概念上例子:
*int 是int的指针类型;
**int是int指针的指针类型;
取变量地址用&操作符,取指针变量对应的变量的值使用*操作符
如:
func main() {
i := 0
var p *int
var pp **int
p = &i
pp = &p
*p++
// i输出i的值
// p变量i的地址
// *p是int指针指向i的值
// pp变量p的地址
// *pp输出的是指针p的地址
fmt.Println(i, p, *p, pp, *pp)
}
指针传入函数的坑
func main() {
student := Student{"A", 1}
fmt.Println("set 前",student)
set(student)
fmt.Println("set 后未变",student)
fmt.Println("set 前",student)
Set(&student)
fmt.Println("set 后指针传入值变了",student)
}
type Student struct {
Name string
Age int
}
// s中的值未变
func set(s Student) Student {
s.Age = 2
s.Name = "B"
return s
}
// 通过指针传递,值变了
func Set(s *Student) {
s.Age = 2
s.Name = "B"
}
2. go的访问权限
go不像java一样有public、private、protected这些关键字来修饰方法或者类等的访问权限,它是通过首字母的大小写来控制可见性的,go中的常量、变量、接口、函数如果首字母是大写相当于java中的public,如
package test
import "fmt"
// 外部的文件可以访问
func TestPointer() {
fmt.Printf("我可以访问")
}
// 结构体Man可以外部访问
type Man struct {
// 外部可以访问赋值
Name string
// 不可以访问
age int
}
3. defer关键字
3.1 defer的表达式必须是函数或方法的调用;
3.2 defer必须等待当前函数执行完了之后再执行,如
func testA() {
fmt.Println("testA")
}
func testB() {
fmt.Println("testB")
}
func unlock() {
fmt.Println("unlock")
}
func testDefer() {
testA()
// 在当前函数执行完之后再执行
defer unlock()
testB()
}
func main() {
testDefer()
}
想象中以为是:testA->unlock->testB,其实输出顺序
3.3 defer所注册的函数返回值是按照LIFO(后进先出)的次序依次执行,如:
不加defer执行结果:
func deferReturn(i int) int {
fmt.Println(i)
return i
}
func main() {
for i := 0; i < 4; i++{
deferReturn(i)
}
}
加入defer
func deferReturn(i int) int {
fmt.Println(i)
return i
}
func main() {
for i := 0; i < 4; i++{
defer deferReturn(i)
}
}
持续维护......