Go语言面向对象和结构体_2021_11_08

结构体

结构体是由一些列属性组成的复合数据类型,下面是一个简单的列子

package main

import "fmt"

type Counter int

type User map[string]string

func main() {

	var counter Counter = 20
	counter += 10
	fmt.Println(counter) //30

	me := make(User)
	me["username"] = "zhangsan"
	me["age"] = "30"
	fmt.Println(me) //map[age:30 username:zhangsan]

	fmt.Printf("%T ,%T \n", counter, me)

	var callback = func(args ...string) {
		for i, v := range args {
			fmt.Println(i, ":", v)
		}
	}

	callback("a", "a", "c")

	var counter2 int = 10
	fmt.Println(int(counter2) > counter2)

}
结构体的定义
package main

import "fmt"

type User struct {
	ID       int
	userName string
	age      int
	Addr     string
	remark   string
	tel      string
}

func main() {
	var user User
	fmt.Printf("%T \n", user) // main.User
	fmt.Printf("%#v\n", user) //main.User{ID:0, userName:"", age:0, Addr:"", remark:"", tel:""}

	var me2 = User{1, "张三", 10, "有道", "kwkw ", "182123455"}
	fmt.Printf("%#v\n", me2) //main.User{ID:1, userName:"张三", age:10, Addr:"有道", remark:"kwkw ", tel:"182123455"}

	var me3 = User{}
	fmt.Printf("%#v\n", me3)

	//指定属性名
	var me4 User = User{ID: 1, userName: "zhangsan", age: 10, Addr: "海南省", remark: "张", tel: "1845"}
	fmt.Printf("%#v\n", me4) //main.User{ID:1, userName:"zhangsan", age:10, Addr:"海南省", remark:"张", tel:"1845"}


	fmt.Printf("%T \n",&me3)	//*main.User 是一个指针类型


	var pointer *User
	fmt.Printf("%T \n",pointer)
	fmt.Printf("%#v \n",pointer)

	var point2 *User = &me2
	fmt.Printf("%#v \n",point2)
	var point3 *User = &User {}
	fmt.Printf("%#v \n",point3)

	//创建结构条的指针的时候,用new
	var pointer4 *User = new (User)
	fmt.Printf("%#v\n",pointer4)



}



结构体的使用
package main

import "fmt"

type MyUser struct {
	ID       int
	userName string
	age      int
	Addr     string
	remark   string
	tel      string
}

func main() {

	me := MyUser{
		userName: "kk",
		ID:       1,
		Addr:     "西安",
	}
	fmt.Println(me)

	me.tel = "182898329839"
	fmt.Printf("%#v\n", me)
	me2 := &MyUser{
		ID:       2,
		userName: "wuha",
	}

	fmt.Printf("%T \n", me2)
	(*me2).tel = "18389389238"

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

	me2.Addr = "北京 "
	fmt.Printf("%#v\n", me2)
}
匿名结构体
package main

import "fmt"

func main() {
	var me struct {
		id   int
		name string
	}

	fmt.Printf("%#v\n", me) // struct { id int; name string }{id:0, name:""}

	me2 := struct {
		Id   int
		name string
	}{1, "2"}

	fmt.Printf("%#v \n", me2)						// struct { Id int; name string }{Id:1, name:"2"}

	
}



结构体中有另外的结构体
package main

import "fmt"

type Address struct {
	Region  string
	Streect string
	No      string
}

type User struct {
	Id   int
	Name string
	Addr Address
}

func main() {

	var me01 User
	fmt.Printf("%#v \n", me01) //main.User{Id:0, Name:"", Addr:main.Address{Region:"", Streect:"", No:""}}

	user := User{
		Id:   1,
		Name: "zhangsan",
		Addr: Address{
			Region:  "北京",
			Streect: "天水街道",
			No:      "002",
		},
	}
	fmt.Printf("%#v \n", user) //main.User{Id:1, Name:"zhangsan", Addr:main.Address{Region:"北京", Streect:"和", No:"002"}}
	fmt.Println(user.Addr.Streect) //天水街道	
}
匿名嵌入
package main

import "fmt"

type Address struct {
	Region  string
	Streect string
	No      string
}

type User struct {
	Id   int
	Name string
	Addr Address
}

type Employee struct {
	User
	Salary float64
}

func main() {

	var me Employee
	fmt.Printf("%T,%#v", me, me)//main.Employee,main.Employee{User:main.User{Id:0, Name:"", Addr:main.Address{Region:"", Streect:"", No:""}}, Salary:0}



}


指针结构体
package main

import "fmt"

type Address struct {
	Region  string
	Streect string
	No      string
}

type User struct {
	Id   int
	Name string
	Addr *Address
}

type Employee1 struct {
	*User
	Salary float64
	Name   string
}

func main() {
	var me01 User
	fmt.Printf("%#v \n", me01)

	me02 := User{
		Id:   1,
		Name: "kk",
		Addr: &Address{
			"西安市",
			"大山",
			"大模大样",
		},
	}
	fmt.Printf("%#v\n", me02)      //main.User{Id:1, Name:"kk", Addr:(*main.Address)(0xc00006e180)}
	fmt.Println(me02.Addr.Streect) //大山
	me02.Addr.Region = "北京市"
	fmt.Printf("%#v\n", me02.Addr) //&main.Address{Region:"北京市", Streect:"大山", No:"大模大样"}

	me03 := Employee1{
		User: &User{
			Id:   1,
			Name: "kk",
			Addr: &Address{
				"西安",
				"业路",
				"iodis",
			},
		},
	}
	fmt.Println(me03.Addr.Streect) //业路

	user1 := User{}
	user2 := user1
	user2.Name = "张三"
	fmt.Printf("%#v\n", user1) //main.User{Id:0, Name:"", Addr:(*main.Address)(nil)}
	fmt.Printf("%#v\n", user2) //main.User{Id:0, Name:"张三", Addr:(*main.Address)(nil)} 按值类型传递
	change(user1)
	fmt.Printf("%#v\n", user1)		//main.User{Id:0, Name:"", Addr:(*main.Address)(nil)} 按值类型传递
	changePoint(&user1)
	fmt.Printf("%#v\n", user1)		//main.User{Id:0, Name:"yyyyyyy", Addr:(*main.Address)(nil)} 按地址传递

	mex := User{
		Id: 1 ,
		Name: "kk ",
		Addr: &Address{"西安","锦业","001"},
	}
	mex2 := mex
	fmt.Println(mex2.Name)		//
	// fmt.Println(mex2.Addr.Streect ) //如果没有初始化 的话 panic: runtime error: invalid memory address or nil pointer dereference



}

func change(u User) {
	u.Name = "xxxxxx"
}

func changePoint(u * User ){
	u.Name = "yyyyyyy"
}

创建新用户
package main
import (
	"fmt"
)
type Address struct {
	Region  string
	Streect string
	No      string
}

type User struct {
	Id   int
	Name string
	Addr Address
}

func NewUser(id int, name string, region string) User {
	return User{
		Id:   id,
		Name: name,
		Addr: Address{
			Region: region,
		},
	}
}

func main() {
	me := User{}
	me2 := me
	me2.Name = "kk"
	fmt.Printf("%#v\n", me) //值类型
	fmt.Printf("%#v\n", me2)
	user := NewUser(1,"iodsoi","83ew98")
	fmt.Printf("%#v\n",user)		//main.User{Id:1, Name:"iodsoi", Addr:main.Address{Region:"83ew98", Streect:"", No:""}}

}


package main
import "fmt"
type Dog struct {
	Name string
}

func (dog Dog) Call(){
	fmt.Printf("%s :汪汪",dog.Name)
}

func main() {
	dog := Dog{"豆豆"}
	dog.Call()				//豆豆 :汪汪
}
package main

import "fmt"

type Address struct {
	Region string
	Street string
	No     string
}

func (addr Address) Addr() string {
	return fmt.Sprintf("%s-%s-%s ", addr.Region, addr.Street, addr.No)
}

type User struct {
	ID   int
	Name string
	Addr Address
}

func (user User) User() string {
	return fmt.Sprintf("[%d]%s:%s", user.ID, user.Name, user.Addr)
}

func (user User) String() string {
	return fmt.Sprintf("[%d]%s:%s", user.ID, user.Name, user.Addr)
}

func main() {
	var u User = User{
		ID:   1,
		Name: "kk",
		Addr: Address{
			Region: "89328",
			Street: "iuiods",
			No:     "iods",
		},
	}
	
	fmt.Printf("%#v\n", u)
	fmt.Println(u.User())      //[1]kk:{89328 iuiods iods}
	fmt.Println(u.Addr.Region) //89328
	fmt.Println(u)             //[1]kk:{89328 iuiods iods}

}

java中的this, 但是在go中一定需要写一个对象

package main

import (
	"fmt"
)

type User struct {
	id   int
	name string
}

func (user User) GetId() int {
	return user.id
}

func (user *User) SetId(id int) {
	user.id = id
}

func (user *User) GetName() string {
	return user.name
}

func (user *User) SetName(name string) {
	user.name = name
}

type Employee struct {
	User
	Salary float64
	name   string
}

func (employee Employee) GetName() string {
	return employee.name
}


func (employee * Employee) SetName(name string) {
	employee.name = name
}

func main() {
	u := User{
		id:   1,
		name: "张三",
	}
	u.SetId(10)
	fmt.Println(u.id)
	u.SetName("哈哈")
	fmt.Println(u.GetName()) //哈哈
	e := Employee{
		User:   User{1, "kk"},
		Salary: 1000,
		name:   "xiaoke",
	}
	fmt.Println(e.GetName())      		//xiaoke
	fmt.Println(e.User.GetName()) 		//kk
	e.SetName(" set userName ") 	//设置的是user的Name
	fmt.Println(e.GetName())      		// 获取到Employee的Name
	fmt.Println(e.User.GetName()) 		// 获取用户名
	e.SetName("哈哈")
	fmt.Println("----------",e.GetName())			// 哈哈
}

方法:
指针接收者
该使用的值接收者还是指针接收者,取决于是否现需要修改原始结构体,若不需要修改则使用值,若需要修改则使用指针,若存在指针接收者,则所有方法的使用指针接收者。
对于 接收者为指针类型的方法 ,需要注意在运行时若接收者为nil用会发生错误 。

若结构体中匿名嵌入带有方法的结构体时,则在外部结构体可以嵌入结构体的方法,并且 在调用时只有嵌入字段会传递给嵌入结构体方法的接收者。
当被嵌入结构体与嵌入结构体具有相同的名称时,则使用对象,方法名调用被嵌入结构体方法,若想要调用嵌入结构体方法,则使用对象嵌入结构体名,方法 。

方法值/方法表达式
方法可以赋值给变量,存储在数组,切片,映射中,可以作为参数传递给函数返回值进行返回 。
方法有两种,一种时使用对象/对象指针调用的方法值,另外一种有类型,类型调用的(方法表达式)
方法值 。
在方法表达式赋值时若方法接收者为值类型,则在赋值时会将值类型拷贝(或调用为指针类型则自动解引用拷贝)

package main

import "fmt"

type Dog struct {
	name string
}


func (dog Dog) Call() {
	fmt.Printf("%s: 汪汪:", dog.name)
}

func (dog *Dog) SetName(name string) {
	dog.name = name
}

func main() {
	dog := Dog{"豆豆"}
	m1 := dog.Call
	fmt.Printf("%T \n", m1)
	m1()
}
package main

import "fmt"

type Dog struct {
	name string
}

func (dog Dog) Call() {
	fmt.Printf("%s %#v  : 汪汪\n", dog.name,&dog)

}

func (dog * Dog) CallPoint() {
	fmt.Printf("%s %#v  : 汪汪\n", dog.name,&dog)

}


func (dog *Dog) SetName(name string) {
	dog.name = name
	fmt.Printf("%#v \n",&dog)
}

func main() {
	dog := Dog{"豆豆"}
	m1 := dog.Call
	fmt.Printf("%T \n", m1)	//func()
	m1()							// 豆豆 : 汪汪

	dog.SetName("小黑")	//
	m1()						//豆豆 : 汪汪

	fmt.Println("============================")

	// 对于值接收者方法 者会拷备一份
	pdog := &Dog{"豆豆"}
	m2 := pdog.Call

	fmt.Printf("%T \n",m2)		//func()
	m2()						//豆豆 : 汪汪

	pdog.SetName("小黑")
	m2()					//豆豆 : 汪汪


	fmt.Println("============================")

	// 对于值接收者方法 者会拷备一份
	pdog1 := &Dog{"豆豆"}
	m3 := pdog1.CallPoint

	fmt.Printf("%T \n",m3)		//func()
	m3()						//豆豆 (**main.Dog)(0xc00000e040)  : 汪汪

	pdog1.SetName("小黑")
	m3()					//小黑 (**main.Dog)(0xc00000e050)  : 汪汪

}
结构体排序
package main

import (
	"fmt"
	"sort"
)

type User struct {
	ID   int
	Name string
}

func main() {

	list := [][2]int{{1, 3}, {5, 9}, {4, 3}, {6, 2}}

	//使用数组中第二个元素比较大小,元素比较大小进行排序
	sort.Slice(list, func(i, j int) bool {
		return list[i][1] < list[j][1]
	})
	fmt.Println(list) //从小到大开始排序
	users := []User{
		{ID: 1, Name: "zhangsan"},
		{ID: 2, Name: "lisi"},
		{ID: 4, Name: "wangwu"},
		{ID: 3, Name: "zhaoliu"},
	}
	sort.Slice(users, func(i, j int) bool {
		return users[i].ID < users[j].ID //从小到大开始排序
	})
	fmt.Println(users) //[{1 zhangsan} {2 lisi} {3 zhaoliu} {4 wangwu}]

}

作业 将用户管理系统改成结构体

package manager

import (
	"fmt"
	"sort"
	"strings"
)

type User struct {
	ID       int
	RealName string
}

//添加用户
func AddUser(users *[]User) {
start:
	var (
		id   int
		name string
	)
	fmt.Println("请输入姓名或退出(q/Q):")
	fmt.Scan(&name)

	if name == "q" || name == "Q" {
		return
	}
	if exits(users, name) {
		fmt.Println(name, " 名字已经存在")
		goto start
	}
	id = GetmaxId(users)
	user := User{ID: id, RealName: name}
	*users = append(*users, user)
	for _, v := range *users {
		fmt.Printf("%#v \t ", v)
	}
	fmt.Println()
	goto start
}

func exits(users *[]User, name string) bool {
	for _, v := range *users {
		if strings.Contains(v.RealName, name) {
			return true
		}
	}
	return false
}

func GetmaxId(users *[]User) int {
	maxId := 1
	for _, v := range *users {
		if maxId < v.ID {
			maxId = v.ID
		}
	}
	maxId = maxId + 1
	return maxId
}

//更新用户
func UpdateUser(users *[]User) {
	fmt.Println("请输入要修改用户姓名:")
	var inputId string
	fmt.Scan(&inputId)
	xx := strings.Split(inputId, "_")
	fmt.Println(xx)
	for _, v := range *users {
		if strings.Contains(v.RealName, xx[0]) {
			v.RealName = xx[1]
			break
		}
	}
}

//删除用户
func DeleteUser(users *[]User) {

start:
	fmt.Println("请删除用户姓名:")
	var inputId string
	fmt.Scan(&inputId)
	if inputId == "q" || inputId == "Q" {
		return
	}
	if inputId == "all" {
		*users = []User{}
	} else {
		for k, v := range *users {
			if strings.Contains(v.RealName, inputId) {
				*users = append((*users)[:k], (*users)[k+1:]...)
				break
			}
		}
	}
	goto start
}

//
func QueryUser(users *[]User) {
start:
	fmt.Println("请输入要查询的用户姓名或退出(q/Q):")
	var inputId string
	fmt.Scan(&inputId)
	if inputId == "q" || inputId == "Q" {
		return
	}
	if inputId == "all" {
		sort.Slice(*users, func(i, j int) bool {
			return (*users)[i].RealName > (*users)[j].RealName
		})
		for _, v := range *users {
			fmt.Printf("%5d | %20s\n", v.ID, v.RealName)
		}
	} else {
		for _, v := range *users {
			if strings.Contains(v.RealName, inputId) {
				fmt.Printf("%5d | %20s \n", v.ID, v.RealName)
				break
			}
		}
	}
	goto start
}



package main

import (
	"fmt"
	"go_learn/20211111/codes/manager"
	"os"
)

func main() {
	callbacks := map[string]func(users *[]manager.User){
		"1": manager.AddUser,
		"2": manager.UpdateUser,
		"3": manager.DeleteUser,
		"4": manager.QueryUser,
	}
	fmt.Println(callbacks)
	//存储用户信息
	users := []manager.User{}
	fmt.Println("欢迎使用用户管理系统:")
	//id := 0
	for {
		var op string
		fmt.Println(`请输入指令:
1.新建用户 2.修改用户 3.删除用户 4.查询用户 q.退出`)
		fmt.Scan(&op)
		if "q" == op {
			os.Exit(500) //直接退出
		}
		callbacks[op](&users)
	}

}


github地址
https://github.com/quyixiao/go_learn.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值