1. 函数与方法
1.1 函数
函数命名:
- 小写:只能本包内调用
- 大写:其他包也可调用
func main() {
sum := add(1, 2)
fmt.Println(sum)
}
func add(a, b int) int {
return a + b
}
1.2 方法
与函数的区别:方法在定义的时候,会在func
和方法名之间增加一个参数,这个参数就是接收者,这样我 们定义的这个方法就和接收者绑定在了一起,称之为这个接收者的方法。
type person struct {
name string
}
func (p person) String() string{
return "the person name is "+p.name
}
func main() {
p:=person{name:"张三"}
fmt.Println(p.String())
}
接收者:
- 值接收者:调用的时候,使用的其实是值接收者的一个副本,所以对该值的任何操作,不会影响原来的类型变量。(不改变原值)
- 指针接收者:传递的是一个指向原值指针的副本,指针的副本,指向的还是原来类型的值,所以修改时,同时也会影响原来类型变量的值。(会改变变量值)
Go编译器自动会解引用:
调用方法时,可以不用在意接收者是什么,采用值或指针调用方法均可,因为Go编译器自动会解引用,以满 足接收者的要求
func main() {
p:=person{name:"张三"}
p.modify() //指针接收者,修改有效
p:=person{name:"张三"}
(&p).modify() //指针接收者,修改有效
fmt.Println(p.String())
}
type person struct {
name string
}
func (p person) String() string{
return "the person name is "+p.name
}
func (p *person) modify(){
p.name = "李四"
}
1.3 可变参数
函数方法的参数,可以是任意多个,这种我们称之为可以变参数,可变参数的定义,在类型前加上省略号… 即可。
func main() {
print("1","2","3")
}
func print (a ...interface{}){
for _,v:=range a{
fmt.Print(v)
}
fmt.Println()
}
1.4 参考
- [Go语言实战笔记(八)| Go 函数方法](https://www.flysnow.org/2017/03/31/go-in-action-go-method.html)
2. golang方法返回局部变量指针
2.1 可以直接返回局部变量的指针
原因:
这主要依赖go是有runtime的语言,编译器在发现有变量可以逃逸出去的时候会在堆上分配变量而不是栈 上,这样就可以返回该变量的指针了,且会使该地址的引用+1,当生命空间结束时,gc会去回收。
与C对比:
C语言就完全需要程序员自己去控制内存了,如果需要从函数内部返回指针,那么需要程序员自己malloc在 堆上分配空间,并且需要在外部使用者用完之后即使的free掉。如果直接像go那样返回指针,要么编译不 过,要么也是返回一个已经不该使用的栈内存地址,使用该地址会造成严重的错误。
package main
import "fmt"
func test() *int {
var inner int = 100
return &inner
}
func main() {
outer := test()
fmt.Println(outer)
}
2.1 参考
- [golang方法返回局部变量指针](https://studygolang.com/articles/17271)
- [Go语言---函数返回局部变量地址](https://blog.csdn.net/li_101357/article/details/80209413)