go语言基本操作--四

这篇具有很好参考价值的文章主要介绍了go语言基本操作--四。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

面向对象编程

对于面向对象编程的支持go语言设计得非常简洁而优雅。因为,Go语言并没有沿袭面向对象编程中诸多概念,比如继承(不支持继承,尽管匿名字段的内存布局和行为类似继承,但它并不是继承)、虚函数、构造函数和析构函数、隐藏的this指针等.
尽管go语言中没有封装,继承,多态这些概念,但同样通过别的方式实现这些特性:
1:封装:通过方法实现
2:继承:通过匿名字段实现
3:多态:通过接口实现

匿名字段作用—继承

一般情况下,定义结构体的时候是字段名与其类型一 一对应,实际上go支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段。
当匿名字段也是一个结构体的时候,那么这个结构体所拥有的全部字段都被隐式地引入了当前定义的这个结构体。

//定义一个结构体类型

type Person struct {
	name string //名字
	sex  byte   //性别
	age  int    //年龄
}

type Student struct {
	Person //只有类型 没有名字,匿名字段,继承了Person的成员
	id     int
	addr   string
}

匿名字段初始化

package main

import "fmt"

//定义一个结构体类型

type Person struct {
	name string //名字
	sex  byte   //性别
	age  int    //年龄
}

type Student struct {
	Person //只有类型 没有名字,匿名字段,继承了Person的成员
	id     int
	addr   string
}

func main() {
	//顺序初始化
	var s1 Student = Student{
		Person{"mike", 'm', 18},
		1,
		"bj",
	}
	fmt.Println("s1 = ", s1) //s1 =  {{mike 109 18} 1 bj}

	//自动推导类型
	s2 := Student{
		Person{"mike", 'm', 18},
		1,
		"bj",
	}
	fmt.Println("s2 = ", s2) //s2 =  {{mike 109 18} 1 bj}
	//%+v 显示更详细
	fmt.Printf("s2 = %+v\n", s2) //s2 = {Person:{name:mike sex:109 age:18} id:1 addr:bj}

	//指定成员初始化,没有初始化的常用自动赋值为0
	s3 := Student{id: 1}
	fmt.Printf("s3 = %+v\n", s3) //s3 = {Person:{name: sex:0 age:0} id:1 addr:}

	s4 := Student{Person: Person{name: "mike"}, id: 1}
	fmt.Printf("s4 = %+v\n", s4) //s4 = {Person:{name:mike sex:0 age:0} id:1 addr:}
}

成员的操作

package main

import "fmt"

//定义一个结构体类型

type Person struct {
	name string //名字
	sex  byte   //性别 字符类型
	age  int    //年龄
}

type Student struct {
	Person //只有类型 没有名字,匿名字段,继承了Person的成员
	id     int
	addr   string
}

func main() {
	//自动推导类型
	s1 := Student{Person{"mike", 'm', 18}, 1, "bj"}

	fmt.Println(s1.name, s1.sex, s1.id, s1.addr, s1.age) //mike 109 1 bj 18
	s1.name = "yoyo"                                     //等价于s1.Person.name = "mike"
	s1.sex = 'f'
	s1.age = 22
	s1.id = 666
	s1.addr = "wh"
	fmt.Println(s1.name, s1.sex, s1.id, s1.addr, s1.age) //yoyo 102 666 wh 22
	s1.Person = Person{"go", 'm', 23}
	fmt.Println(s1.name, s1.sex, s1.id, s1.addr, s1.age) //go 109 666 wh 23
}

同名字段

package main

import "fmt"

//定义一个结构体类型

type Person struct {
	name string //名字
	sex  byte   //性别 字符类型
	age  int    //年龄
}

type Student struct {
	Person //只有类型 没有名字,匿名字段,继承了Person的成员
	id     int
	addr   string
	name   string //和Person同名了
}

func main() {
	//声明(定义一个变量)
	var s Student
	//默认规则(就近原则),如果能在本作用域找到此成员,就操作此成员
	//如果没有找到,找到继承的字段
	s.name = "mike" //操作的是Student的name
	s.sex = 'm'
	s.age = 18
	s.addr = "bj"
	fmt.Printf("s = %+v\n", s) //s = {Person:{name: sex:109 age:18} id:0 addr:bj name:mike}

	//显示调用
	s.Person.name = "yoyo"
	fmt.Printf("s = %+v\n", s) //s = {Person:{name:yoyo sex:109 age:18} id:0 addr:bj name:mike}
}

非结构体匿名字段

package main

import "fmt"

//定义一个结构体类型

type mystr string //自定义类型,给一个类型改名

type Person struct {
	name string //名字
	sex  byte   //性别 字符类型
	age  int    //年龄
}

type Student struct {
	Person //只有类型 没有名字,匿名字段,继承了Person的成员
	int    //基础类型的匿名字段
	mystr  //基础类型的匿名字段
}

func main() {
	s := Student{Person{"mike", 'm', 18}, 666, "hehehe"}
	fmt.Printf("s = %+v\n", s) //s = {Person:{name:mike sex:109 age:18} int:666 mystr:hehehe}

	fmt.Println(s.name, s.age, s.sex, s.int, s.mystr) //mike 18 109 666 hehehe
	fmt.Println(s.Person, s.int, s.mystr)             //{mike 109 18} 666 hehehe

	s.Person = Person{"go", 'm', 22}
	fmt.Println(s.Person, s.int, s.mystr)             //{go 109 22} 666 hehehe
	fmt.Println(s.name, s.age, s.sex, s.int, s.mystr) //go 22 109 666 hehehe
}

结构体指针类型匿名字段

package main

import "fmt"

//定义一个结构体类型

type mystr string //自定义类型,给一个类型改名

type Person struct {
	name string //名字
	sex  byte   //性别 字符类型
	age  int    //年龄
}

type Student struct {
	*Person //指针类型
	id      int
	addr    string
}

func main() {
	s1 := Student{&Person{"mike", 'm', 18}, 1, "wh"}
	fmt.Println("s1 = ", s1)                             //s1 =  {0xc00008e380 1 wh}
	fmt.Println(s1.name, s1.sex, s1.age, s1.id, s1.addr) //mike 109 18 1 wh

	//先定义变量
	var s2 Student
	s2.Person = new(Person) //分配空间
	s2.name = "yoyo"
	s2.sex = 'm'
	s2.age = 19
	s2.id = 2
	s2.addr = "wh"
	fmt.Println("s2 = ", s2)                             //s2 =  {0xc000054400 2 wh}
	fmt.Println(s2.name, s2.sex, s2.age, s2.id, s2.addr) //yoyo 109 19 2 wh
}

方法介绍—封装

在面向对象编程中,一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些函数,这种带有接收者的函数,我们称为方法。本质上,一个方法则是一个和特殊关联的函数。
一个面向对象的程序会用方法来表达其属性和对应的操作,这样使用这个对象的用户就不需要直接去操作对象,而是借助方法来做这种事情。
在Go语言中,可以任意自定义类型(包括内置类型,但不包括指针类型)添加相应的方法。
方法总是绑定对象实例,并隐式将实例作为第一实参(receiver),方法的语法如下:
func (receiver ReceiverType) funcName(parameters)(results)
1:参数receiver可任意命名.如方法中未曾使用,可以省略参数.
2: 参数receiver类型可以是T或*T。基类型T不能是接口或者指针
3:不支持重载方法,也就是说,不能定义名字相同但是不同参数的方法。

面向过程和面向对象函数区别

package main

import "fmt"

// 实现2数相加
// 面向过程
func Add01(a, b int) int {
	return a + b
}

// 面向对象,方法:给某个类型绑定一个函数
type long int //改名

// tmp叫接收者,接收者就是传递的一个参数
func (tmp long) Add02(other long) long {
	return tmp + other
}

func main() {

	result := Add01(1, 1)            //普通函数调用方式
	fmt.Println("result = ", result) //result = 2

	//定义一个变量
	var a long = 2

	//调用方法格式
	add1 := a.Add02(3)
	fmt.Println("result = ", add1) //result =  5

	//面向对象只是换了一种表现形式
}

结构体类型添加方法

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

//带有接收者的函数叫方法

func (tmp Person) PrintInfo() {
	fmt.Println("tmp = ", tmp)
}

// 通过一个函数,给成员赋值
func (p *Person) SetInfo(name string, sex byte, age int) {
	p.name = name
	p.sex = sex
	p.age = age
}
func main() {
	//定义同时初始化
	p := Person{"mike", 'm', 18}
	p.PrintInfo() //tmp =  {mike 109 18}

	//定义一个结构体变量
	var p2 Person

	(&p2).SetInfo("yoyo", 'm', 19)
	p2.PrintInfo() //tmp =  {yoyo 109 19}
}
type pointer *int
//pointer 为接收者类型,它本身不能是指针类型
func (tmp pointer) test(){} //error invalid receiver type pointer

//不支持重载,只要接收者类型不一样,这个方法就算同名,也是不同方法,不会出现重复定义函数的错误

func (tmp Person) PrintInfo() {
	fmt.Println("tmp = ", tmp)
}

type char byte

func (tmp char) PrintInfo() {

}

值语义和引用语义

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

// 接收者为普通变量,非指针,值语义,一份拷贝
func (p Person) SetInfoValue(name string, sex byte, age int) {
	p.name = name
	p.sex = sex
	p.age = age
	fmt.Println("SetInfoValue p = ", p)      //SetInfoValue p =  {mike 109 19}
	fmt.Printf("SetInfoValue &p = %p\n", &p) //SetInfoValue &p = 0xc00008e3c0
}

// 接收者为指针变量,引用传递
func (p *Person) SetInfoPoubter(name string, sex byte, age int) {
	p.name = name
	p.sex = sex
	p.age = age
	fmt.Printf("SetInfoPoubter p = %p\n", &p) //SetInfoPoubter p = 0xc00008e380
	fmt.Println("SetInfoPoubter &p = ", *p)   //SetInfoPoubter &p =  {mike 109 19}
}
func main() {

	s1 := Person{"go", 'm', 18}

	fmt.Printf("&s1 = %p\n", &s1) //&s1 = 0xc00008e380
	//值语义
	s1.SetInfoValue("mike", 'm', 19)
	fmt.Println("s1 = ", s1) //s1 =  {go 109 18}

	//引用语义
	(&s1).SetInfoPoubter("mike", 'm', 19)
	fmt.Println("s1 = ", s1) //s1 =  {mike 109 19}
}

指针类型和普通类型的方法集

指针类型的方法集

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

// 接收者为普通变量,非指针,值语义,一份拷贝
func (p Person) SetInfoValue() {
	fmt.Println("SetInfoValue")
}

// 接收者为指针变量,引用传递
func (p *Person) SetInfoPoubter() {
	fmt.Println("SetInfoPoubter")
}
func main() {
	//假如,结构体是一个指针变量,它能够调用那些方法,这些方法就是一个集合,简称方法集
	p := &Person{"mike", 'm', 18}

	p.SetInfoPoubter()

	(*p).SetInfoPoubter() //把(*p)转换成p调用,等价于上面

	//内部做的转换,先把指针p,转成*p后再调用
	//(*p).SetInfoValue()
	p.SetInfoValue()
}

普通类型的方法集

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

// 接收者为普通变量,非指针,值语义,一份拷贝
func (p Person) SetInfoValue() {
	fmt.Println("SetInfoValue")
}

// 接收者为指针变量,引用传递
func (p *Person) SetInfoPoubter() {
	fmt.Println("SetInfoPoubter")
}
func main() {

	p := Person{"mike", 'm', 18}

	p.SetInfoPoubter() //内部会先把p转化为&p再调用(&p).SetInfoPoubter()

	p.SetInfoValue()
}

方法的继承

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

// Person类型,实现一个方法
func (tmp *Person) PrintInfo() {
	//PrintInfo: name = mike,sex = m, age = 18
	fmt.Printf("PrintInfo: name = %s,sex = %c, age = %d\n", tmp.name, tmp.sex, tmp.age)
}

// 有一个学生,继承Person字段,成员和方法都继承了
type Student struct {
	Person //匿名字段
	id     int
	addr   string
}

func main() {
	s := Student{Person{"mike", 'm', 18}, 666, "bj"}
	s.PrintInfo()
}

方法的重写

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

// PrintInfo Person类型,实现一个方法
func (tmp *Person) PrintInfo() {
	//PrintInfo: name = mike,sex = m, age = 18
	fmt.Printf("PrintInfo: name = %s,sex = %c, age = %d\n", tmp.name, tmp.sex, tmp.age)
}

// PrintInfo Student也实现了一个方法,这个方法和Person方法重名,这个方法叫重写
func (tmp *Student) PrintInfo() {
	//PrintInfo: name = mike,sex = m, age = 18
	fmt.Println("Student: tmp = ", tmp)   //Student: tmp =  &{{mike 109 18} 666 bj}
	fmt.Println("Student: *tmp = ", *tmp) //Student: *tmp =  {{mike 109 18} 666 bj}
}

// Student 有一个学生,继承Person字段,成员和方法都继承了
type Student struct {
	Person //匿名字段
	id     int
	addr   string
}

func main() {
	s := Student{Person{"mike", 'm', 18}, 666, "bj"}
	//就近原则:先找本作用域的方法,找不到再用继承的方法
	s.PrintInfo() //这样会调用Student的

	//显示调用继承的方法
	s.Person.PrintInfo() //PrintInfo: name = mike,sex = m, age = 18
}

方法值

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

func (p Person) SetInfoValue() {
	fmt.Printf("SetInfoValue: %p,%v\n", &p, p)
}

func (p *Person) SetInfoPointer() {
	fmt.Printf("SetInfoPointer %p, %v\n", p, *p) //SetInfoPointer 0xc00008e380, {mike 109 18}
}

func main() {

	p := Person{"mike", 'm', 18}
	fmt.Printf("main: %p,%v\n", &p, p) //main: 0xc00008e380,{mike 109 18}

	p.SetInfoPointer() //传统调用方式

	//保存方式入口地址
	pFunc := p.SetInfoPointer //这个就是方法值,调用函数时,无需再传递接收者,隐藏了接收者
	pFunc()                   //等价于p.SetInfoPointer() SetInfoPointer 0xc00008e380, {mike 109 18}

	vFunc := p.SetInfoValue
	vFunc() //等价于p.SetInfoValue() SetInfoValue: 0xc000054440,{mike 109 18} 值传递
}

方法表达式

package main

import "fmt"

type Person struct {
	name string
	sex  byte
	age  int
}

func (p Person) SetInfoValue() {
	fmt.Printf("SetInfoValue: %p,%v\n", &p, p)
}

func (p *Person) SetInfoPointer() {
	fmt.Printf("SetInfoPointer %p, %v\n", p, *p) //SetInfoPointer 0xc00008e380, {mike 109 18}
}

func main() {

	p := Person{"mike", 'm', 18}
	fmt.Printf("main: %p,%v\n", &p, p) //main: 0xc00008e380,{mike 109 18}

	p.SetInfoPointer() //传统调用方式

	//方法值,f := p.SetInfoPointer//隐藏了接收者

	//方法表达式
	f := (*Person).SetInfoPointer
	fmt.Println("=========")
	f(&p) //显示把接收者传递过去 ---->p.SetInfoPointer() SetInfoPointer 0xc0000543a0, {mike 109 18}

	f2 := (Person).SetInfoValue
	f2(p) //SetInfoValue: 0xc000054440,{mike 109 18}
}

接口类型介绍

在go语言,接口是一个自定义类型,接口类型具体描述了一系列方法的集合。
接口类型时一种抽象的类型,它不会暴露出它所代表的对象的内部值的结构和这个对象支持的基础操作的集合,它们只会展示出它们自己的方法。因此接口类型不能将其实例化。
接口定义:
1:接口命令习惯以er结尾
2:接口只有方法声明,没有实现,没有数据字段
3:接口可以匿名嵌入其他接口,或嵌入到结构中

接口的定义和实现

package main

import "fmt"

// Humaner 定义接口类型
type Humaner interface {
	//方法,只有声明,没有实现,由别的类型(自定义类型)实现
	sayhi()
}

type Student struct {
	name string
	id   int
}

// Student实现了此方法
func (tmp *Student) sayhi() {
	fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)

}

type Teacher struct {
	addr  string
	group string
}

// Teacher实现了此方法
func (tmp *Teacher) sayhi() {
	fmt.Printf("Teacher[%s, %s] sayhi\n", tmp.addr, tmp.group)

}

type MyStr string

// MyStr实现了此方法
func (tmp *MyStr) sayhi() {
	fmt.Printf("MyStr[%s] sayhi\n", *tmp)
}

type MyStr1 string

func (tmp MyStr1) sayhi() {
	fmt.Printf("MyStr1[%s] sayhi\n", tmp)
}

func main() {
	//定义接口类型的变量
	var i Humaner

	//只要实现了此接口方法的类型,那么这个类型的变量(接收者类型)就可以给i赋值
	s := &Student{"mike", 666}
	i = s
	i.sayhi() //Student[mike, 666] sayhi

	t := &Teacher{"wh", "go"}
	i = t
	i.sayhi() //Teacher[wh, go] sayhi

	var str MyStr = "hello cheng"
	i = &str
	i.sayhi() //MyStr[hello cheng] sayhi

	var str1 MyStr1 = "hello"
	i = str1
	i.sayhi() //MyStr1[hello] sayhi
}

多态的表现

package main

import "fmt"

// Humaner 定义接口类型
type Humaner interface {
	//方法,只有声明,没有实现,由别的类型(自定义类型)实现
	sayhi()
}

type Student struct {
	name string
	id   int
}

// Student实现了此方法
func (tmp *Student) sayhi() {
	fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)

}

type Teacher struct {
	addr  string
	group string
}

// Teacher实现了此方法
func (tmp *Teacher) sayhi() {
	fmt.Printf("Teacher[%s, %s] sayhi\n", tmp.addr, tmp.group)

}

type MyStr string

// MyStr实现了此方法
func (tmp *MyStr) sayhi() {
	fmt.Printf("MyStr[%s] sayhi\n", *tmp)
}

type MyStr1 string

func (tmp MyStr1) sayhi() {
	fmt.Printf("MyStr1[%s] sayhi\n", tmp)
}

// 定义一个普通函数,函数的参数为接口类型
// 只有一个函数,可以有不同表现,多态
func WhoSayHi(i Humaner) {
	i.sayhi()
}

func main() {

	s := &Student{"mike", 666}
	t := &Teacher{"wh", "go"}
	var str MyStr = "hello cheng"
	var str1 MyStr1 = "hello"
	//调用同一函数,不同表现,多态,多种形态
	WhoSayHi(s)
	WhoSayHi(t)
	WhoSayHi(&str)
	WhoSayHi(str1)

	//创建一个切片
	x := make([]Humaner, 4)
	x[0] = s
	x[1] = t
	x[2] = &str
	x[3] = str1

	//第一个返回下标,第二个返回鞋标所对应的值
	for _, data := range x {
		fmt.Println("===========")
		WhoSayHi(data)
	}
}

接口继承—(接口嵌入)

如果一个interface1作为interface2的一个嵌入字段,那么interface2隐式地包含了interface1里面的方法。

package main

import "fmt"

// Humaner 定义接口类型
type Humaner interface { //子集
	//方法,只有声明,没有实现,由别的类型(自定义类型)实现
	sayhi()
}

type Personer interface { //超集
	Humaner //匿名字段,继承了sayhi()

	sing(lrc string)
}

type Student struct {
	name string
	id   int
}

// Student实现了此方法
func (tmp *Student) sayhi() {
	fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)

}

func (tmp *Student) sing(lrc string) {
	fmt.Println("Student在唱着:", lrc)
}

func main() {

	//定义一个接口类型的变量
	var i Personer
	s := &Student{"mike", 666}
	i = s
	i.sayhi()    //继承过来的方法 //Student[mike, 666] sayhi
	i.sing("三月") //Student在唱着: 三月
}

接口转换

package main

import "fmt"

// Humaner 定义接口类型
type Humaner interface { //子集
	//方法,只有声明,没有实现,由别的类型(自定义类型)实现
	sayhi()
}

type Personer interface { //超集
	Humaner //匿名字段,继承了sayhi()

	sing(lrc string)
}

type Student struct {
	name string
	id   int
}

// Student实现了此方法
func (tmp *Student) sayhi() {
	fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)

}

func (tmp *Student) sing(lrc string) {
	fmt.Println("Student在唱着:", lrc)
}

func main() {

	//超集可以转换为子集,反过来不可以
	var iPro Personer //超集

	iPro = &Student{"mike", 666}
	var i Humaner //子集
	//cannot use i (variable of type Humaner) as Personer value in assignment:
	//Humaner does not implement Personer (missing method sing)
	//iPro = i //error

	i = iPro //OK 超集可以转换为子集
	i.sayhi()
}

空接口

空接口不包含任何的方法,正因为如此,所有的类型都实现了空接口,因此空接口可以存储任意类型,它有点类似于C语言的void*类型。
go语言基本操作--四,golang,开发语言,后端

package main

import "fmt"

func xxx(args ...interface{}) {
	
}

func main() {
	//空接口万能类型,保存任意类型的值

	var i interface{} = 1
	fmt.Println("i = ", i)

	i = "abc"
	fmt.Println("i = ", i)
}

通过if实现类型断言

go语言基本操作--四,golang,开发语言,后端文章来源地址https://www.toymoban.com/news/detail-696055.html

package main

import "fmt"

type Student struct {
	name string
	id   int
}

func main() {

	i := make([]interface{}, 3)

	i[0] = 1                    //int
	i[1] = "hello go"           //string
	i[2] = Student{"mike", 666} //Student

	//类型查询,类型断言
	//第一个返回下标,第二个返回下标对应的值,data是i[0],i[1],i[2]
	for index, data := range i {
		//第一个返回值,接口变量本身,第二个返回判断结果的真假
		if value, ok := data.(int); ok == true {
			fmt.Printf("x[%d] 类型为int,内容为%d\n", index, value) //x[0] 类型为int,内容为1
			fmt.Println("int data = ", data)                 //int data =  1
			fmt.Println("------------------")
		} else if value, ok := data.(string); ok == true {
			fmt.Printf("x[%d] 类型为string, 内容为%s\n", index, value) //x[1] 类型为string, 内容为hello go
			fmt.Println("string data = ", data)                  //string data =  hello go
			fmt.Println("------------------")
		} else if value, ok := data.(Student); ok == true {
			fmt.Printf("x[%d] 类型为Student, 内容为name = %s, id = %d\n", index, value.name, value.id) //x[2] 类型为Student, 内容为name = mike, id = 666
			fmt.Println("Student data = ", data)                                                 //Student data =  {mike 666}
			fmt.Println("------------------")
		}
	}
}

通过switch实现类型断言

package main

import "fmt"

type Student struct {
	name string
	id   int
}

func main() {

	i := make([]interface{}, 3)

	i[0] = 1                    //int
	i[1] = "hello go"           //string
	i[2] = Student{"mike", 666} //Student

	//类型查询,类型断言
	//第一个返回下标,第二个返回下标对应的值,data是i[0],i[1],i[2]
	for index, data := range i {
		switch value := data.(type) { //type参数类型
		case int:
			fmt.Printf("x[%d] 类型为int,内容为%d\n", index, value) //x[0] 类型为int,内容为1
			fmt.Println("int data = ", data)                 //int data =  1
			fmt.Println("------------------")
		case string:
			fmt.Printf("x[%d] 类型为string, 内容为%s\n", index, value) //x[1] 类型为string, 内容为hello go
			fmt.Println("string data = ", data)                  //string data =  hello go
			fmt.Println("------------------")
		case Student:
			fmt.Printf("x[%d] 类型为Student, 内容为name = %s, id = %d\n", index, value.name, value.id) //x[2] 类型为Student, 内容为name = mike, id = 666
			fmt.Println("Student data = ", data)                                                 //Student data =  {mike 666}
			fmt.Println("------------------")
		}
	}
}

到了这里,关于go语言基本操作--四的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • R语言——基本操作(一)

    目录 一、基本操作 二、R包的安装及使用 三、获取帮助 四、内置数据集 五、数据结构 六、向量索引 七、向量运算 参考 Rstudio 控制台常用快捷键 Ctrl + ↑ : 查看所有历史记录,比直接使用 ↑ 查找更方便 Esc: 中断操作,可中断未完成的操作(未完成回车后是 + ),也可以

    2024年04月15日
    浏览(27)
  • 链表的基本操作(c语言)

    目录 链式存储结构 代码实现 链表初始化 头插法(前插法)创建含k个结点的单链表 尾插法(后插法)创建含k个结点的单链表 取第i个节点的数据域 寻找数据域等于e的结点返回该结点序号 在第i个结点插入数据域为e的结点 删除第i个结点 遍历链表 求链表结点个数(链表长度) 销毁

    2024年02月08日
    浏览(41)
  • 【Golang】认识Go语言中基本的数据类型

    目录 整形 基本整型  特殊整型 浮点型 布尔型 字符型 字符串转义符  多行字符串 字符串的常用操作 复数 我们不论在学习什么语言中,我们都要去认识一下这个语言中的数据类型,当然学习Go也不例外,我们也要去认识一下其相关的数据类型,当然这些数据类型基本上是大

    2023年04月08日
    浏览(45)
  • C语言实现链表基本操作

    目录 一、什么是链表 二、为什么要使用链表 三、链表相关知识 四、链表实现 1.定义结构体 2.创建链表 3.遍历链表 4.判断链表是否为空 5.计算链表长度 6.插入一个数据 7.删除数据 8.全部代码 如果把数据比喻成珠子,指针就是线,链表通过指针这条线就是把数据这些珠子串起

    2024年02月06日
    浏览(42)
  • 顺序表基本操作算法——基础代码(C语言)

     创建一个顺序表(数据元素个数为5), 输出顺序表中的所有数据元素 查找第3个位置上的元素 查找元素15是否在顺序表中,如果在,请输出该元素在顺序表中的位置 在顺序表中的第1个位置插入数据0 删除刚刚插入的元素 输出顺序表中的所有数据元素 运行结果如下  

    2024年02月06日
    浏览(46)
  • C语言第十一课--------操作符的使用与分类-------基本操作

             作者介绍:           作者id : 老秦包你会 , 简单介绍:              喜欢学习C语言和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨                                 个人主页::小小页面                                   gitee页面

    2024年02月14日
    浏览(45)
  • 【数据结构】链栈的基本操作(C语言)

    零零总总搜索了一些关于链栈的资料,了解了链栈的基本操作,一直觉得别人写的代码或多或少存在一些问题,所以打算自己写一篇关于链栈的文章,也算是对所学知识的梳理和巩固了。 首先说明本文使用C语言进行链栈的基本操作,链栈是无头结点的。这里补充说明一下,

    2024年02月05日
    浏览(56)
  • 【数据结构】队列基本操作的实现(C语言)

    🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🐌 个人主页:蜗牛牛啊 🔥 系列专栏:🛹数据结构、🛴C++ 📕 学习格言:博观而约取,厚积而薄发 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与

    2024年02月16日
    浏览(48)
  • 【数据结构】 链栈的基本操作 (C语言版)

    目录 一、链栈 1、链栈的定义: 2、链栈的优缺点: 二、链栈的基本操作算法(C语言)     1、宏定义   2、创建结构体 3、链栈的初始化   4、链栈的进栈 5、链栈的出栈 6、获取栈顶元素 7、栈的遍历输出 8、链栈的判空  9、求链栈的栈长 10、链栈的清空 11、链栈的销毁

    2024年01月24日
    浏览(48)
  • 单链表的基本操作代码实现(C语言版)

    目录 前言: 单链表的基本操作 准备工作(头文件、各种宏定义以及结构体定义) 一.较简单操作 1.单链表的初始化 2.判断单链表是否为空表 3.单链表的销毁 4.单链表的清空 5.求单链表的表长 二.较重要操作 1.单链表的取值 2.单链表元素的查找 3.单链表的结点插入 4.单链表的结

    2024年04月11日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包