栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

你知道go的结构体吗?嘿嘿

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

你知道go的结构体吗?嘿嘿

结构体

结构体之前呢,我们先谈谈数据类型,这里我们有基础类型外,还可以自定义类型和给类型设置别名。

  • 两者都可以使用type来设置,如下

  • 可以很清楚的看到哈,加了等号就是设置别名,不加就是自定义类型哈。
  • 那么我们结构体也是要用到type的,再加上struct , 这个和c/c++里面的差不多哈
type 类型名 struct {
		字段名 	字段类型
		字段名 	字段类型
		。。。。
}
  • 意思的话,就跟java里面的类一样,举个例子

  • 还可以使用匿名的结构体,临时用一下的时候定义。
结构体的初始化
package main

import "fmt"

// 一个人的类型

type person struct {
	name   string
	age    int
	gender string
	hobby  []string
}

func main() {
	var sb person
	sb.name = "骚包"
	sb.age = 18
	sb.gender = "男"
	sb.hobby = []string{"打篮球", "看妹妹"}
	fmt.Printf("%#v", sb)
	fmt.Println()

	var kk = person{
		name:   "科科",
		age:    14,
		gender: "女",
	}
	fmt.Println(kk)

	as := person{
		"阿水",
		12,
		"男",
		[]string{"打篮球"},
	}

	fmt.Println(as)

}

  • 一共三种方式
  • 第一种:通过声明变量,通过变量来传入值
  • 第二种,通过key/value的形式来直接输入值
  • 第三种,类似全部属性的构造器一样的输入值,按照顺序
方法
  • go里面的方法跟java区别还是满大的,go的方法其实就是一个函数,但是要求限定了调用的结构体
  • 如下:

func main() {
	ans := newDog("骚包", 18)
	ans.wang()
}
  • 这样子看,是不是很明显了,通过变量.wang()的形式就可以调用了,这个倒是跟java里面一样,啊哈哈哈哈哈

在go里面哈,如果标识符首字母大写了,就表示对外部包可见(暴露的,公有的)

  • 上面的 (d dog) 这个就是接受者,用来指定被调用的对象
  • 接受者,也会分为, 值接受者, 和 指针接受者
值接收者 和 指针接收者
  • 上图解释,因为我知道,代码别说你不看了,我也不会看呀,啊哈哈哈哈哈

  • 可以看出来哈,初始化的时候他是18岁
  • 调用值接收者呢,年龄没有发生改变哈,
  • 但是调用 指针接收者, 年龄就发生了改变
  • 这是因为,go里面全部都是值传递,复制粘贴的形式,CV的意思,值传递后进行修改,改的是传过去的副本,而不是原数据,所以不会发生改变,
  • 但是指针就直接指向的是原数据。
什么时候要使用到 指针类型接收者呢

1.需要修改接收者里面的值
2.接收者是拷贝比较大的大对象
3.保证一致性,如果有某个方法使用了指针接收者,那么其他方法也要使用指针接收者

学了这么久了,我们来搞个学生管理系统吧
package main

import (
	"fmt"
	"os"
)

// 学生类
type student struct {
	id   int64
	name string
}

// 构造器
func newStudent(id int64, name string) *student {
	return &student{
		id,
		name,
	}
}

// 设置一个容器,用来装学生
var (
	allStu map[int64]*student
)

// 展示所有学生
func allStudent() {
	for k, v := range allStu {
		fmt.Printf("学号:%d  姓名:%sn", k, v.name)
	}
}

// 添加一个学生
func addStudent() {
	var (
		id   int64
		name string
	)
	fmt.Print("请输入您的学号:")
	fmt.Scanln(&id)
	fmt.Print("请输入您的姓名:")
	fmt.Scanln(&name)
	new := newStudent(id, name)
	allStu[id] = new
}

// 删除一个学生
func delStudent() {
	fmt.Print("请输入想要删除的学号:")
	var (
		id int64
	)
	fmt.Scanln(&id)
	delete(allStu, id)
}

func main() {
	allStu = make(map[int64]*student, 50)
	for {
		fmt.Println("欢迎来到学生管理系统!")
		fmt.Println(`
			1.查看所有学生信息
			2.添加一个学生
			3.删除一个学生
			4.退出系统
		`)
		fmt.Print("请问你要运行什么功能!请输入指定数字:")
		var selectID int64
		fmt.Scanln(&selectID)
		switch selectID {
		case 1:
			allStudent()
		case 2:
			addStudent()
		case 3:
			delStudent()
		case 4:
			os.Exit(1)
		default:
			fmt.Println("没有这选项,要退出请按4")
		}
	}

}

  • 要不是代码太长 了,我肯定上图片的,啊哈哈哈哈哈
  • 当然啦,这只是一个函数版本,我们学了方法满,当然可以改写成方法版本
匿名结构体
  • 这玩意很少用到,大多是用在匿名嵌套结构体里面,
  • 当有两个结构体有了重复的字段的时候,我们可以将它抽取出来
  • 例如:人类里面有省和城市,公司类里面也有省和城市
type address struct {
	province string
	city     string
}

type person struct {
	name string
	age  int
	address
}

type company struct {
	name string
	address
}
  • 先三个结构体,地区包装在address里面

  • 结果呢就是一样的,只是这样方便一点。
序列化: 将结构体转为 json
  • json作为现在最流行的传输数据的格式,当然要会转啦
  • 直接上图

  • 值得注意的是两点,
  • 第一点: 首字母必须大写,前面也有说过,只有大写才能进行一个外部包的暴露,才能被调用。
  • 第二点:json转完之后肯定是要继续全部小写的,这里可以用··这个符号来,就是感叹号左边那个东东。然后声明一个转了之后的别名,还能设置数据库的,和配置文件的别名哦
反序列化
  • 然后我们再看看反序列化
	// 反序列化
	s := `{"name":"小阿吉","age":17}`
	var p2 person
	json.Unmarshal([]byte(s), &p2)
	fmt.Printf("%#vn", p2)
	// 输出效果:  main.person{Name:"小阿吉", Age:17}
  • 这个还是没有问题的,就一个地方注意点就好啦。
  • 在传值的时候,要进行传指针哦,不然修改的就是副本的值哦。原来的数据就不会发生改变了。传指针 传指针 传指针 传指针

今天就到这里把,晚上继续。。。。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/342880.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号