Go语言学习第3关

1. 指针 make new

package main

import "fmt"

func main(){
    
    
	var a int = 1
	fmt.Printf("%d--%T--%p\n",a,a,&a)
	var p = &a //p的类型 *int p存a的地址 当然p也有自己的地址
	fmt.Println(p,*p)

	//指针是引用数据类型 必须先分配内存
	var i = new(int)
	fmt.Printf("%v--%T--%v\n",i,i,*i)
}

2. 结构体

package main

import "fmt"
import "sort"

//标准形式
func sum(x int, y int) int {
    
    
	return x + y
}

//可变参数x是一个切片 若要和固定参数结合使用把固定参数放前面
func sumN(x ...int) int {
    
    
	var sum int
	for _, v := range x {
    
    
		sum += v
	}
	return sum
}

//多返回值
func cal(x, y int) (int, int) {
    
    
	sum := x + y
	sub := x - y
	return sum, sub
}

//封装函数实现切片的排序
func sortS(slice []int) []int {
    
    
	for i := 0; i < len(slice); i++ {
    
    
		for j := i + 1; j < len(slice); j++ {
    
    
			if slice[i] > slice[j] {
    
    
				temp := slice[i]
				slice[i] = slice[j]
				slice[j] = temp
			}
		}
	}
	return slice
}

//实现map对象按key排序
func sortMap(m map[string]string) string {
    
    
	var sliceKey []string
	for k, _ := range m {
    
    
		sliceKey = append(sliceKey, k)
	}
	sort.Strings(sliceKey)
	var str string
	for _, v := range sliceKey {
    
    
		str += fmt.Sprintf("%v=>%v\t", v, m[v])
	}
	return str
}

//自定义函数类型
type calc func(int, int) int

func add(x, y int) int {
    
    
	return x + y
}

//函数作为参数
func calcPro(x, y int, op func(int, int) int) int {
    
    
	return op(x, y)
}

//函数作为返回值
type calType func(int,int) int

func do(o string) calType {
    
    
	switch o {
    
    
	case "*":
		return func(x, y int) int {
    
    
			return x * y
		}
	default:
		return nil
	}
}

func main() {
    
    
	sum := sum(4, 5)
	fmt.Println(sum)
	sumN := sumN(1, 2, 3, 4, 5)
	fmt.Println(sumN)

	fmt.Println(sortS([]int{
    
    2, 6, 3, 9, 4}))
	m1 := map[string]string{
    
    
		"user":   "hi",
		"age":    "20",
		"gender": "man",
	}
	fmt.Println(sortMap(m1))

	var c calc
	c = add
	d := add
	fmt.Printf("%T %T\n", c, d) //main.calc func(int, int) int

	//匿名函数
	j := calcPro(3, 4, func(i1, i2 int) int {
    
    
		return i1 * i2
	})
	fmt.Println(j)

	e := do("*")
	fmt.Println(e(9,9))
}

3. 结构体方法

package main

import "fmt"

//结构体方法
type Person struct{
    
    
	Name string
	Age int
}
func (p Person) PrintInfo(){
    
    
	fmt.Printf("%v %v\n",p.Name,p.Age)
}
func (p *Person) SetInfo(name string,age int){
    
    
	p.Name = name
	p.Age = age
}

//匿名字段 不能重复
type Person1 struct{
    
    
	string
	int
}

//给自定义类型添加方法
type myInt int
func (m myInt) PrintMyInfo(){
    
    
	fmt.Println("***")
}

func main(){
    
    
	var p1 = Person{
    
    
		Name: "dou",
		Age: 10,
	}
	p1.PrintInfo()

	var a myInt = 10
	a.PrintMyInfo()
}

4. 结构体继承

package main

import "fmt"

type Person struct{
    
    
	Name string
	Age int
	Hobby []string
	Map map[string]string

	myToy Toy	//结构体嵌套
}
func (p Person) run(){
    
    
	fmt.Println("running")
}

type Toy struct{
    
    
	size int
}

type Student struct{
    
    
	Id int
	Person //结构体嵌套 也就是继承
}
func (s Student) runS(){
    
    
	fmt.Println("student running")
}

func main(){
    
    
	var p Person
	p.Age = 10
	p.Name = "dou"
	p.Hobby = make([]string, 2,2)
	p.Hobby[0] = "a"
	p.Hobby[1] = "b"
	p.Map = make(map[string]string)
	p.Map["address"] = "hangzhou"
	p.Map["phone"] = "123"

	p.myToy.size = 18

	fmt.Printf("%#v\n",p)

	//继承
	var s = Student{
    
    
		Id: 989898,
		Person: Person{
    
    
			Age:10,
			Name:"dou",
		},
	}
	s.run()
	s.runS()

}

5. go mod 和Golang包

  • go mod init (项目名称)
  • 注意大写是公有变量 包外可访问 小写不能访问到
  • 一个文件夹是一个包 一个包里可以有很多go文件
  • 导入路径怎么写?看go.mod文件怎么写的
  • 下载第三方包
    • go get …
    • 怎么引入? GitHub上看看
    • 引入go程序后 运行 go mod download 下载至项目中 在GOPATH中找 编辑器看不见
    • 可以go mod vendor 将其直接复制到本地 编辑器可见

6. 接口

接口定义

package main

import "fmt"

type Usber interface{
    
    
	start()
	stop()
}
//接口里有方法需通过结构体或自定义类型实现接口
type Camera struct{
    
    

}
func (c Camera) start(){
    
    
	fmt.Println("camera start")
}
func (c Camera) stop(){
    
    
	fmt.Println("close..")
}

//须实现所有方法
type Phone struct{
    
    
	Name string
}
func (p Phone) start(){
    
    
	fmt.Println(p.Name+"\tstart")
}
func (p Phone) stop(){
    
    
	fmt.Println("close..")
}
func main(){
    
    
	p := Phone{
    
    
		Name: "huawei",
	}
	p.start()

	var p1 Usber
	p1 = p
	p1.start()

	c := Camera{
    
    }
	var c1 Usber = c //相机实现了Usb接口
	c1.start()
}

example

package main

import "fmt"

type Usber interface{
    
    
	start()
	stop()
}

type Computer struct{
    
    

}
func (c Computer) work(usb Usber){
    
    
	//断言的应用
	if _,ok := usb.(Phone); ok{
    
    
		usb.start()
	}else{
    
    
		usb.stop()
	}
}

type Phone struct{
    
    
	Name string
}
func (p Phone) start(){
    
    
	fmt.Println(p.Name+"\tstart")
}
func (p Phone) stop(){
    
    
	fmt.Println("close..")
}

type Camera struct{
    
    

}
func (c Camera) start(){
    
    
	fmt.Println("camera start")
}
func (c Camera) stop(){
    
    
	fmt.Println("close..")
}

func main(){
    
    
	var c = Computer{
    
    }
	var p = Phone{
    
    
		Name: "iphone",
	}
	var ca = Camera{
    
    }

	c.work(p)
	c.work(ca)
}

空接口 类型断言

package main

import "fmt"

//空接口可做函数参数(切片值 map值)表示任意类型

func show(a interface{
    
    }){
    
    
	fmt.Printf("%v--%T\n",a,a)
}

func main(){
    
    
	show(20)
	show("douqiyuan")
	show(9.4632)

	//类型断言
	var a interface{
    
    }
	a = "hi golang"
	v,ok := a.(string)
	fmt.Println(v,ok)
	//有什么用? 用switch case 根据类型做不同操作
}

结构体值接收者和指针接收者实现接口的区别

结构体方法中的(p Phone)即为接收者 此处是值接收者

package main

import(
	"fmt"
)

type Usber interface{
    
    
	start()
	stop()
}

type Phone struct{
    
    
	Name string
}
//值接收者
func (p Phone) start(){
    
    
	fmt.Println(p.Name+"\tstart")
}
func (p Phone) stop(){
    
    
	fmt.Println("close..")
}

type Camera struct{
    
    

}
//指针接收者
func (c *Camera) start(){
    
    
	fmt.Println("camera start")
}
func (c *Camera) stop(){
    
    
	fmt.Println("close..")
}

func main(){
    
    
	//结构体值接收者实例化后的结构体值类型和结构体指针类型都可赋值给接口变量
	var p = Phone{
    
    
		Name: "huawei",
	}
	var u Usber = p //手机实现usb接口
	u.start()
	var p1 = &Phone{
    
    
		Name: "huawei",
	}
	var u1 Usber = p1
	u1.start()

	//结构体指针接收者实例化后的只有结构体指针类型才可以赋值给接口变量
	var c = &Camera{
    
    }
	var u2 Usber = c
	u2.start()
}

有指针类型接收者时 实例化就要加地址 再去实现接口
空接口类型不好索引 搭配断言即可

猜你喜欢

转载自blog.csdn.net/m0_73482105/article/details/126968070