# go 语言学习

go 的初始化方式,要么用

a := or var a =

# 切片

注意切片

b := a[1:2]
	fmt.Println(&b[0], &a[1])

结果:

image-20220112151117086

拥有相同的地址空间,也就是说,切片实际上只是一个引用。

var s2 = make([]int, 2)
fmt.Printf("s2: %v\n", s2)
s2 = append(s2, 1, 2, 3)
fmt.Printf("s2: %v\n", s2)
fmt.Println(len(s2))

即使用 make 指定了切片的大小,它也可以扩容。

要从切片 a 中删除索引为 index 的元素,操作方法是 a = append(a[:index], a[index+1:]...)

copy 作为切片的拷贝,如果直接用 = 则是引用。

# Map

初始化:

aMap := make(map[keyType]valueType, cap)

cap 只是预设的大小,mao 是可以动态增长的,这和 C 语言很类似。

aMap := make(map[int]*[]int)
tmp := []int{1, 2, 3}
aMap[0] = &tmp
fmt.Printf("aMap: %v\n", aMap)
tmp01 := *aMap[0]
for k, v := range tmp01{
	fmt.Println("")
}

aMap := make (map [int]*[] int) : 设置 map 的值类型为切片指针

aMap := make (map [int][] int): 设置 map 的值类型为切片

# 判断是否有键
t, ok := my["address"]
if ok{
	fmt.Printf("t: %v\n", t)
}

t, ok := my["address"]

用这个方式

# 闭包

闭包就是函数加引用环境。

image-20220112172405621

add 函数返回的就是一个函数,但是这个返回的函数会引用外部的变量 x。

也就是说 f 在其生命周期中,x 会一直存在。

输出:

image-20220112172511760

闭包其实并不复杂,只要牢记 闭包=函数+引用环境

# 递归

尾递归求解斐波拉切数列

package main
import "fmt"
func fab(n, n1, n2 int) int {
	if n == 0 {
		return n1
	}
	return fab(n-1, n1+n2, n1)
}
func main() {
	fmt.Println(fab(10, 1, 0))
}

# Init

go 中有特殊的函数: init 函数,它会在执行 main 函数之前自动执行。

func main() {
	fmt.Println(fab(10, 1, 0))
}
func init(){
	fmt.Println("init.....")
}

结果:

image-20220112174831802

会先于 main 函数自动执行,并且一个源文件中可以有多个 init 函数。

# 类型定义和类型别名

类型定义:

type NewType Type

类型别名:

type NewType = Type

# 结构体

未初始化的结构体,成员都是零值 int 0 float 0.0 bool false string nil nil

初始化方式有列表初始化和部分初始化,可以看 golang 结构体的初始化

struct 可以用 new 来初始化:

pb := new(Book)

pb 是实例化的 Book 结构。

# 接口

这个接口有点搞。。。

首先,接口定义:

type Shape interface {
	Area() float32
	
}

接口中定义方法类型。

结构体需要实现接口

type Square struct {
	sideLen float32
	
}
type Triangle struct {
	Bottom float32
	Height float32
	
}
type Shape interface {
	Area() float32
	
}
func (s Square) Area() float32{
	return s.sideLen * s.sideLen
}
func (t Triangle) Area() float32{
	return t.Bottom*t.Height/2
}

可以看到针对正方形和三角形分别实现了 Area 函数。

# 接口的使用:
t := Triangle{1, 2}
s := Square{4}
shapes := []Shape{t, s}
for _, shape:= range shapes{
fmt.Printf("shape.Area(): %v\n", shape.Area())
}
var sh Shape
sh = t
fmt.Printf("sh.Area(): %v\n", sh.Area())
sh = s
fmt.Printf("sh.Area(): %v\n", sh.Area())

也可以用结构体的指针来对接口进行赋值。

# 嵌套接口
package main
import "fmt"
type Fly interface {
	fly()
}
type Swim interface {
	swim()
}
type FlyFish interface {
	Fly
	Swim
}
type fish struct {
}
func (f fish) fly() {
	fmt.Println("flying")
}
func (f fish) swim() {
	fmt.Println("swimming")
}
func main() {
	var flyfish FlyFish
	flyfish = fish{}
	flyfish.fly()
	flyfish.swim()
}

FlyFish 是一个嵌套接口,它实现了 Fly 和 Swim 两个接口,但实际上只要把嵌套接口中所有方法都实现就可以了。

# 继承

package main
import "fmt"
type Animal struct {
	name string
	age  int
}
func (animal Animal) eat() {
	fmt.Println("eat...")
}
func (animal Animal) sleep() {
	fmt.Println("sleep...")
}
type Dog struct {
	Animal
	color string
	
}
type Cat struct {
	Animal
	color string
	
}
func main() {
	dog := Dog{
		Animal{"huahua",16},
		"red",
	}
	dog.eat()
	dog.sleep()
	cat := Cat{
		Animal{"yuanyuan", 1},
		"black",
	}
	cat.sleep()
	cat.eat()
}

# 反射

package main
import (
	"fmt"
	"reflect"
)
func main() {
	// utils.Test()
	type MyInt int
	var x MyInt = 6
	z := reflect.TypeOf(x)
	v := reflect.ValueOf(x)
	// fmt.Printf("%v", z)
	fmt.Println(v.Kind())
	fmt.Println(z.Kind())
	fmt.Println(z)
	fmt.Println(v)
	var a interface{}
	t := "hello"
	a = t
	value, ok := a.(string)
	if ok{
		fmt.Println("can convert")
		fmt.Println(string(value))
	}else{
		fmt.Println("cant do convert")
	}
	va, ok := a.(float32)
	if ok{
		fmt.Println(va)
	}else{
		fmt.Println("not float32")
	}
}
更新于

请我喝[茶]~( ̄▽ ̄)~*

Kalice 微信支付

微信支付

Kalice 支付宝

支付宝