当前位置: 首页 > news >正文

golang学习总结--结构体、接口

目录

 

结构体--定义

结构体--声明与初始化

结构体--tag

结构体--匿名成员

结构体--继承、多继承

结构体--方法

interface(接口)

interface--定义

interface--使用

interface--空接口


结构体--定义

type struct_variable_type struct {
         member member_type
         member member_type
        ......
}
 
go结构体中的成员可以是任意类型
例子:
type Student struct {
    name string
    age int       //小写私有成员(对外不可见)
    Class string  //首字母大写则该成员为公有成员(对外可见) 
}

结构体--声明与初始化

1.成员赋值形式
    var stu1 Student	
    stu1.age = 18
    stu1.name = "xiaoluo"
    stu1.Class = "go"

2 new 函数创建
    var stu2 *Student = new(Student)
    stu2.name = "xiaoluo"
    stu2.age = 20

3 &形式创建
	var stu3 *Student = &Student{
		name:  "rose",
		age:   18,
		Class: "go", // 如果分行的时候每行都要,
	}

4 KV 形式初始化值
    var stu4 Student = Student{ // KV 形式初始化值
		name:  "xiaoluo",
		age:   18,
		Class: "Go", // 注意这里的逗号不能少
	}

5 值顺序初始化
    var stu5 Student = Student{ // 顺序形式 形式初始化值
		"xiaoluo",
		18,
		"go", // 注意这里的逗号不能少
	}

6 nil结构体
    var stu6 *Student = nil

结构体--tag

tag可以为结构体的成员添加说明或者标签便于使用,这些说明可以通过反射获取到。
结构体中的成员首字母小写对外不可见,但是我们把成员定义为首字母大写这样与外界进行数据交互会带来极大的不便,此时tag带来了解决方法

tag --json序列化和反序列化

package main

import (
	"encoding/json"
	"fmt"
)

type Student struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func main() {
	var stu = Student{Name: "xiaoluo", Age: 18}
	data, err := json.Marshal(stu)
	if err != nil {
		fmt.Println("json encode failed err:", err)
		return
	}
	fmt.Println("stu: ", string(data)) //{"name":"xiaoluo","age":18}

	var stu2 Student
	err = json.Unmarshal(data, &stu2) // 反序列化
	fmt.Println("stu2: ", stu2)       // {xiaoluo 18}
}

结构体--匿名成员

结构体中,每个成员不一定都有名称,也允许字段没有名字,即匿名成员。

同一种类型匿名成员只允许最多存在一个。

当匿名成员是结构体时,且两个结构体中都存在相同字段时,优先选择最近的字段。

package main

import "fmt"

type Person struct {
	Name string
	Age  int
}
type Student struct {
	score  string
	Age    int
	Person // 匿名内嵌结构体
}

func main() {
	var stu = new(Student)
	stu.Age = 22                         //优先选择Student中的Age
	fmt.Println(stu.Person.Age, stu.Age) // 0,22
}

结构体--继承、多继承

当结构体中的成员也是结构体时,该结构体就继承了这个结构体,继承了其所有的方法与属性,当然有多个结构体成员也就是多继承。

访问父结构中属性也使用“.”,但是当子结构体中存在和父结构中的字段相同时候,只能使用:"子结构体.父结构体.字段"访问父结构体中的属性,如上面示例的stu.Person.Age 

继承结构体可以使用别名,访问的时候通过别名访问,如下面示例man1.job.Salary

//struct-继承、多继承
package main

import "fmt"

type Person struct {
	Name string
	Age  int
}
type Teacher struct {
	Salary int
	Class  string
}

type Man struct {
	sex    string
	job    Teacher //别名,继承Teacher
	Person         //继承Person
}

func main() {
	var man1 = new(Man)
	man1.Age = 18
	man1.Name = "xiaoluo"
	man1.job.Salary = 1
	fmt.Println("man1:", man1, man1.job.Salary) //&{ {1 } {xiaoluo 18}} 1

	var man2 = Man{
		sex: "女",
		job: Teacher{
			Salary: 2,
			Class:  "班主任",
		},
		Person: Person{ // 匿名初始化方式
			Name: "xiaoluo老师",
			Age:  18,
		},
	}
	fmt.Println("man2", man2)  //{女 {2 班主任} {xiaoluo老师 18}}
}

结构体--方法

一个类型加上它的方法等价于面向对象中的一个类。
一个重要的区别是:在 Go 中,类型的代码和绑定在它上面的
方法的代码可以不放置在一起,它们可以存在在不同的源文件, 唯一的要求是:它们必须是同一个包的
定义方法 的格式
func(recv recevier_type)methodName(parameter_list)(return_value_list){}
package main

import (
	"fmt"
	"math"
)

type Circle struct {
	x      int
	y      int
	Radius int
}

// 面积
func (c Circle) Area() float64 {
	return math.Pi * float64(c.Radius) * float64(c.Radius)
}

// 周长
func (c Circle) Circumference() float64 {
	return 2 * math.Pi * float64(c.Radius)
}

func (c Circle) expand() {
	c.Radius *= 2
}

func (c *Circle) expand2() {
	c.Radius *= 2
}
func main() {
	var c = Circle{Radius: 50}
	fmt.Println(c.Area(), c.Circumference())
	// 指针变量调用方法形式上是一样的
	var pc = &c
	fmt.Println(pc.Area(), pc.Circumference())

	c.expand()
	fmt.Println(c.Radius) //50

	c.expand2()
	fmt.Println(c.Radius) //100

}

interface(接口)

Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能包含任何变量

interface--定义

type 接口名称 interface {
    method1 (参数列表) 返回值列表
    method2 (参数列表) 返回值列表
    ...
}

interface--使用

如果一个接口没有任何方法,我们称为空接口,由于空接口没有方法, 任意结构体都 隐式地实现了空接
要实现一个接口, 必须实现该接口里面的所有方法
//interface使用

package main

import "fmt"

//定义接口
type Skills interface {
	Running()
	Getname() string
}

type Student struct {
	Name string
	Age  int
}

// 实现接口
func (p Student) Getname() string { //实现Getname方法
	return p.Name
}

func (p Student) Running() { // 实现 Running方法
	fmt.Printf("%s running\n", p.Name)
}

func main() {
	var skill Skills
	var stu1 Student
	stu1.Name = "xiaoluo"
	stu1.Age = 12
	skill = stu1
	skill.Running() //调用接口
	fmt.Println(skill.Getname())
}

interface--空接口

go语言内置了一个空接口,名字叫interface{}

空接口里面没有方法,所以它也不具有任何能力。它可以容纳任意类型对象。比如一个字典的 key 是字符串,但是希望 value 可以容纳任意类型的对象,

// 空接口
package main

import "fmt"

func main() {

	var user = map[string]interface{}{
		"age":     30,
		"address": "Beijing Tongzhou",
		"married": true,
	}
	fmt.Println(user)
	// 类型转换语法
	var age = user["age"].(int)
	var address = user["address"].(string)
	var married = user["married"].(bool)
	fmt.Println(age, address, married)

	user["price"] = 5.5
	var price = user["price"].(float64) 
	fmt.Println("user: ", user, price)
}

 

相关文章:

  • 解决运行时报错:error while loading shared libraries xxx.so,cannot open shared object file
  • 超实用:linux shell光标移动常用快捷键
  • git commit之后如何撤销
  • golang学习总结--协程、channel
  • 跟我一起写dockerfile
  • dockerfile中多个FROM指令的意义(multistage)
  • dockerfile实战:使用dockerfile制作c/c++程序docker镜像
  • c++11并发编程一(std::thread之:thread构造函数)
  • c++11并发编程二(std::thread之:线程入口函数)
  • 身份证校验码计算:根据身份证前17位计算第18位校验码-c++实现
  • c++11并发编程三(使用std::future、std::promise获取线程返回值)
  • mysql删除表时报错:Cannot delete or update a parent row: a foreign key constraint fails 解决办法
  • mysql C API 预处理接口
  • C++多个头文件中可以定义同名的namespace吗?
  • 解决mysql 1602错误:Error Duplicate entry ‘***‘ for key ‘PRIMARY‘
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • Angular Elements 及其运作原理
  • CSS居中完全指南——构建CSS居中决策树
  • docker容器内的网络抓包
  • mysql 5.6 原生Online DDL解析
  • Mysql5.6主从复制
  • nodejs调试方法
  • Vue学习第二天
  • WebSocket使用
  • 实习面试笔记
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • gunicorn工作原理
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #QT项目实战(天气预报)
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (差分)胡桃爱原石
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (二)pulsar安装在独立的docker中,python测试
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (南京观海微电子)——I3C协议介绍
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)平衡树
  • ***通过什么方式***网吧
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .net CHARTING图表控件下载地址
  • .NET Core 版本不支持的问题
  • .net 按比例显示图片的缩略图
  • .NET 命令行参数包含应用程序路径吗?
  • .net 微服务 服务保护 自动重试 Polly
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .net对接阿里云CSB服务