//函数
/*
函数声明
func name(parameter-list) (result-list) {
body
}
示例:
func add(a int, b int) int {
return a + b
}
函数add接收两个int参数,返回一个int参数
示例:
func sub(x, y int) (z int) {
z = x - y
return
}
函数sub接收两个int参数,返回一个名为z的int参数
示例:
func person(age int, name string) (int, string) {
myAge := age
myName := name
return myAge, myName
}
_, name := person(11, "TOM")
函数将返回两个值,第一个为int类型,第二个为string类型
我不想接收第一个参数,就用_占位符,_不能读取也不能写入
示例:
func person( getAge func(name string)int, name string) {
getAge(name)
}
func getAge(name string) int {
return 18
}
person(getAge, "Tom")
还可以把函数作为参数传给另一个函数
示例:
func nums(a int, b int) func()int {
return func(a int, b int) int { return a + b }
}
nums(1, 2)()
还可以将函数当作返回值.
函数接收参数的时候,都会复制其参数的副本。
值得注意的是,当传入的是数组时,拷贝的是整个数组,所以函数内部不能改变原数组。
而传入的是slice时,拷贝的是指向底层数组的指针,所以函数内部可以改变原silce。
匿名函数
fmt.Println(func () int { return 1}() )
变长函数
func sum(vals ...int) int {
total := 0
for _, val := range vals {
total += val
}
return total
}
...int代表可以传入任意个int参数
sum()
sum(1)
sum(1, 2, 3, 4)
vals := []int{1, 2, 3 , 4}
sum(vals...)
延迟函数
一个函数什么时候结束:返回之后(执行完return之后)
defer关键字使得被修饰的语句执行在返回之后,函数结束之前。
当有多个 defer 行为被注册时,它们会以逆序执行(类似栈,即后进先出)
示例:
package main
import (
"fmt"
)
func main() {
fmt.Println("defer begin")
defer fmt.Println(1)
defer fmt.Println(2)
// 最后一个放入, 位于栈顶, 最先调用
defer fmt.Println(3)
fmt.Println("defer end")
}
*/
//方法
/*
在Go中方法是方法,函数是函数,两者概念不同
方法的声明和普通函数的声明类似,只是在函数名字前多了一个参数。
这个参数把这个方法绑定到这个参数对应的类型上。
示例:
type nums struct {
a int
}
func (m nums)sub(n nums) int {
return m.a - n.a
}
m := nums{2}
n := nums{1}
fmt.Println( m.sub(n) )
方法前面接收声明类型的参数,那只有该参数的实体能过通过.进行调用。
示例:
type nums struct {
a int
}
func (m *nums)sub(n nums) int {
return m.a - n.a
}
m := nums{2}
n := nums{1}
fmt.Println( (&m).sub(n) )
往往方法前的实体比较大,所以用指针会更好
也可以将方法变成像函数那样调用
示例:
type nums struct {
a int
}
func (m nums)sub(n nums) int {
return m.a - n.a
}
m := nums{2}
n := nums{1}
mySub := m.sub
fmt.Println( mySub(n) )
示例:
type nums struct {
a int
}
func (m nums)sub(n nums) int {
return m.a - n.a
}
m := nums{2}
n := nums{1}
mySub := nums.sub
fmt.Println( mySub(m, n) )
*/
//封装
/*
如果变量或者方法是不能通过对象访问到的,这称作封装的变量或者方法。
Go语言只有一种方式控制命名的可见性:
定义时,首字母大写的就是可从包中导出的,不大写就不能。
同样的机制也同样作用于结构体内的字段和类型中的方法。
结论就是,要封装一个对象,必须使用结构体。
另一个必须注意的是,Go语言中封装的单元是包。无论是函数内的代码还是方法内
的代码,结构体类型内的字段对于同一个包中的所有代码都是可见的。
*/