一、函数定义和调用
package main
import (
"fmt"
)
func test() {
fmt.Println("hello world")
}
func main() {
test()
}
二、函数的参数
1.单个参数
func test(n int) {
fmt.Println("传递进来的参数是", n)
}
func main() {
test(10)
}
2.多个参数
func test(x, y int, s string) {
fmt.Println(x)
fmt.Println(y)
fmt.Println(s)
}
func main() {
test(10, 20, "hello")
}
3.传递不定长参数(切片)
func test(x ...int) {
fmt.Println(x)
fmt.Println("x的类型为", reflect.TypeOf(x))
}
func main() {
test(10, 20, 30, 40)
}
4.定义返回值
在形参括号的后边定义返回参数的类型
func test(x ...int) int {
var sum int
for _, v := range x {
sum += v
}
return sum
}
func main() {
var sum = test(10, 20, 30, 40)
fmt.Println("sum = ", sum)
}
5.函数变量的作用域
变量是先在函数内找,没有在在全局找。
三、匿名函数
var test2 = func() {
fmt.Println("hello world")
}
四、高阶函数
1.高阶函数之函数作为参数
package main
import (
"fmt"
"time"
)
func test(f func()) {
var start = time.Now().Unix()
f()
var end = time.Now().Unix()
t := end - start
fmt.Printf("此程序使用%d秒的时间", t)
}
func f1() {
time.Sleep(time.Second * 1)
}
func main() {
test(f1)
}
2.高阶函数之函数作为返回值
这里不在写了,就是python中的装饰器概念。在go中,在一个函数内声明另外一个函数必须使用匿名函数
五、闭包
引用了一个外部的 非全局的自由变量的函数称为闭包函数。闭包主要解决的问题是 "全局变量污染"的问题
实例:
解释:i就是那个 外部的非全局的自由变量
conter的匿名函数就是闭包函数
func getCounter() func() {
var i = 0
counter := func() {
i++
fmt.Println(i)
}
return counter
}
func main() {
counter := getCounter()
counter()
counter()
counter()
}
六、结构体
go中结构体的概念和C中结构体概念一样。都是多个数据类型的集合
1.定义结构体
type 类型名 struct {
字段1 字段1类型
字段2 字段2类型
…
}
例子:
type student struct {
name string
age int
gender string
class string
}
2.实例化
2.1 先声明后赋值
type student struct {
name string
age int
gender string
class string
}
var s1 student
s1.name = "zhangsan"
s1.age = 20
fmt.Println(s1)
2.2 声明并赋值
这里讲了两种方式
type student struct {
name string
age int
gender string
class string
}
var s = student{"zhangsan", 20, "boy", "1班"}
fmt.Println("s = ", s)
var s1 = student{name: "lisi", age: 21}
fmt.Println("s1 = ", s1)
3.结构体的方法接收器
(s stdent)就是和read方法绑定了
read是自定义方法名称
package main
import "fmt"
type student struct {
name string
age int
}
func (s student) read() {
fmt.Printf("这是%s实例的接收器", s.name)
}
func main() {
s1 := student{"zhangsan", 10}
s1.read()
}
4.匿名字段
//正常我们按照格式来这样定义一个结构体
type student struct {
name string
age int
}
4.1 普通匿名字段
匿名字段就是省略字段的名字,直接写类型,如下:
但是不建议这样做
type student struct {
string
int
}
func main() {
var s1 = student{"zhangsan", 20}
fmt.Println(s1.string, s1.int)
}
4.2 结构体嵌套的匿名字段
注意:s1是student结构体类型的实例,student中没有name字段,但是AA中有,所有s1可以直接s1.name这样使用
type AA struct {
name string
}
type student struct {
string
int
AA
}
func main() {
var s1 = student{"zhangsan", 20, AA{"lisi"}}
fmt.Println(s1.string, s1.int, s1.name)
}
4.3 结构体的继承
结构体的继承就是面向对象中的继承,4.2当中的例子就是继承
七、结构体序列化
序列化和反序列化
package main
import (
"encoding/json"
"fmt"
)
//注意结构体名字和字段名字都要大写
type Student struct {
Name string `json:"name"`
Age int `json:"age"`
Gender string `json:"gender"`
}
func main() {
s2 := Student{}
//序列化
s1 := Student{"zhangsan", 20, "boy"}
s1_json, _ := json.Marshal(s1)
fmt.Println("s1序列化得结果为:", string(s1_json))
//反序列化
json.Unmarshal(s1_json, &s2)
fmt.Println("s1反序列化得结果为:", s2)
}