最全【GO语言卵细胞级别教程】11,2024年最新大厂面试经验分享

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

var a2 Stu = Stu{
Name:“谢思肖”,
Age:21,
}
fmt.Println(a2)


3. 指针声明的两种方式



// 3.指针声明
var a3 *Stu = &Stu{“龙丹丹”, 18}
fmt.Println(a3, *a3)


4. 指针声明使用key赋值



var a4 *Stu = &Stu{
Name:“谢思肖”,
Age:21,
}
fmt.Println(a4, *a4)


5. 完整的代码



package mystudy
// 面向对象 结构体之方法
import “fmt”
type Stu struct{
Name string
Age int
}

func DemoObjStruct(){
fmt.Println(“------结构体声明方法------”)
// 1.直接赋值方式,但顺序不能变
var a1 Stu = Stu{“张三”, 19}
fmt.Println(a1)
// 2.使用key赋值:注意最后一个结尾要加逗号
var a2 Stu = Stu{
Name:“谢思肖”,
Age:21,
}
fmt.Println(a2)
// 3.指针声明
var a3 *Stu = &Stu{“龙丹丹”, 18}
fmt.Println(a3, *a3)
var a4 *Stu = &Stu{
Name:“谢思肖”,
Age:21,
}
fmt.Println(a4, *a4)
}


### 1.5使用包导入结构体


不同包之间引用


1. 首选要大写结构体
2. 在调用的函数中导入包



文件:stu.go
package mystudy
// 这里要大写大写
type Stu struct{
name string
age int
}
/// 调用

文件main.go
package main
import “模块名称/mystudy”
func main(){
var st mystudy.Stu = mystudy.Stu{“lisi”, 22}
}


方案2:针对小写的结构体如何对外使用呢,这里借助一个桥梁,就是对外开放的函数  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/5a47bc384b8749e9a52f864ae33ebdab.png)


1. 首先定义结构体
2. 定义一个外部可以访问的函数
3. 访问函数以修改结构体  
 定义 mystudy.go



package mystudy
// 面向对象 结构体之方法
import “fmt”

type teacher struct{
Name string
age int
}

func InitTeacher(name string, age int)*teacher{
return &teacher{name, age}
}

func DemoObjStruct(){
var te *teacher
te = &teacher{“wagn”, 22}
fmt.Println(te)
(*te).Name = “www”
fmt.Println(te)
}


定义主函数



package main

import (
“fmt”
“com.gdzs/goproject/src/com/gdzs/mystudy”
)
func main(){
te := mystudy.InitTeacher(“青青”, 28)
fmt.Println(te)
(*te).Name = “qingqing”
// 也可以写成 te.Name = “qingqing”
fmt.Println(te)
}

// 输出结果
&{青青 28}
&{qingqing 28}


注意


1. 以上的teacher的属性需要首字母大写,主函数中才可以使用te.Name修改,如果是小写则无法访问,就会报如下错误



main.go:86:8: (*te).name undefined (type mystudy.teacher has no field or method name)


2. 注意声明的时候,不能使用var xxx mystudy.teacher,因为这个结构体是不对外使用的,所以只能使用xxx:=xx这种隐式声明类型的方式。


### 1.6结构体嵌入


#### 1.6.1 嵌入方式1:匿名结构体


结构体嵌入(Struct embedding)是一种在一个结构体中嵌入另一个结构体的方式,以便通过嵌入的结构体来访问其字段和方法。


通过结构体嵌入,可以将一个结构体类型作为另一个结构体的字段,使得被嵌入的结构体的字段和方法成为了外部结构体的一部分,就好像它们是直接定义在外部结构体中一样。


使用结构体嵌入的主要目的是实现代码的重用和组合。通过嵌入结构体,可以将通用的字段和方法提取到一个单独的结构体中,并在其他结构体中嵌入该结构体,从而实现代码的复用,并且可以通过外部结构体访问嵌入结构体的字段和方法。



package mystudy
// 结构体嵌入知识点
import “fmt”
type Animal struct{
Name string
Age int
}

func getAnimal(name string, age int)*Animal{
return &Animal{name, age}
}

func(a Animal) eat(){
fmt.Println(a.Name, “吃东西”)
}

type Dog struct{
Animal // 嵌入结构体
weight int
}

func (d Dog) call(){
fmt.Println(d.Name,“叫了一声,说她的体重是:”,d.weight)
}
func (d *Dog) setWight(weight int){
(*d).weight = weight
fmt.Println(d.weight)
}

func DemoQianru(){
// 声明方式1
var d Dog = Dog{Animal{“花花”, 22}, 108}
fmt.Println(d)
// 声明方式2
// 在 Go 语言中,结构体的字段初始化可以按照顺序进行赋值。
// 但是在嵌套结构体中,如果嵌入的结构体没有指定字段名,
// 那么在初始化时不能省略字段名。
var d2 Dog = Dog{Animal:Animal{“兰兰”, 22}, weight:108}
fmt.Println(d2)
d.setWight(99)
fmt.Println(d)
// 声明方式3使用指针
var d3 *Dog = &Dog{Animal:Animal{“雨雨”, 22}, weight:108}
(*d3).setWight(98)
fmt.Println((*d3))
}


嵌入的结构体可以通过变量直接调用,如上代码所示



// 访问方式1
d2.weight
// 访问方式2
d2.Animal.Name


对于指针,这几种方式调用都是可以使得



对于指针,这几种方式调用都是可以使得s
fmt.Println(d3.Animal.Name)
fmt.Println(d3.Name)
fmt.Println((*d3).Name)


#### 1.7.2结构体嵌入:当作一个字段


1. 一个结构体当作一个类型来嵌入结构体中



type Dog struct {
a Animal // Animal结构体被嵌入到Dog结构体中
}


2. 声明和调用方法
	1. 声明:var c1 = cat{Animal{“猫猫”, 19}, 180}
	2. 调用方式:c1.a.XXX



package mystudy
// 结构体嵌入知识点
import “fmt”
type Animal struct{
Name string
Age int
}

func getAnimal(name string, age int)*Animal{
return &Animal{name, age}
}

func(a Animal) eat(){
fmt.Println(a.Name, “吃东西”)
}

type cat struct{
a Animal
high int
}

func DemoQianru(){
fmt.Println(“------结构体嵌入,当作类型------”)
// 声明
var c1 = cat{Animal{“猫猫”, 19}, 180}
fmt.Println(c1)
// 此语句无法调用,会报错
// 16.结构体嵌入.go:59:17: c1.Name undefined (type cat has no field or method Name)
// fmt.Println(c1.Name)
// 使用以下带调用
fmt.Println(c1.a.Name)
}


通过以上如果想通过类来实现的话,还得是使用嵌入的匿名结构体,因为它会自动搜索结构体中的属性的。不需要指定具体的属性


### 1.7面向对象-封装


有了1.6章节的嵌入结构体可以看到要是实现封装的话,使用嵌入匿名的结构体可以完成。


#### 1.7.1给她创建一个类吧


在 Go 语言中,没有类的概念,而是使用结构体(struct)和方法(method)来实现面向对象的编程。  
 可以通过定义一个结构体来表示一个类型,并在该结构体上定义方法来操作和处理该类型的实例。这种结构体和方法的组合可以用来模拟类的概念。


下面是一个创建结构体和方法的示例:  
 (1)首字母大写,其他包可以访问,否则,只能在当前包可以访问  
 (2)属性也是一样的,大写首字母可以对外访问,否则只能当前包可以访问  
 (3)方法也是如此:方法使用结构体绑定方法


1. 定义一个类



package mystudy
// 类知识
type Student struct{
Name string
age int
}


2. 创建构造函数:因为结构体都是值传递,所以这里使用指针



func getStudent(name string, age int)*Student{
return &Student(name, age)
}


3. 创建方法:使用结构体绑定方法  
 注意这里设置需要传入指针,才能改变对应的值



func (s *Student)setName(name string){
(*s).Nmae = name
}

func (s Student)getName(){
return s.Name
}


#### 1.7.2类的继承


类继承:使用嵌入匿名结构体即可  
 (1)实现父类结构体,实现子类结构体,子类结构体嵌入匿名父类结构体  
 (2)同样定义了showInfo()方法 必须参数和返回值都一样,不能出现参数不同,返回值不同的同名函数,否则会报错  
 (3)当调用的时候会先在子类中寻找方法或者属性,如果找不到再调用父类的



// 定义父类结构体
type People struct{
Name string
Age int
}
// 定义父类方法
func (p People)showInfo()string{
fmt.Println(“父类方法showInfo”)
message := fmt.Sprinf(“我的名字:%v 我的年龄”,p.Name, p.Age)
return message
}
// 定义父类方法
func (p People)whoami(){
fmt.Println(“我是谁:”, p.Name)
}

// 定义子类结构体
type Student struct{
People
notes string
}
// 定义子类发方法
func(s Student) showInfo()string{
fmt.Println(“子类方法showInfo”)
message := fmt.Sprinf(“我的名字:%v 我的年龄”,s.Name, s.Age)
return message
}


完整的测试代码



package mystudy
// 面向对象-继承
import “fmt”

// 定义父类结构体
type People struct{
Name string
Age int
}
func (p *People)setName(name string){
(*p).Name = name
}

// 定义父类方法
func (p People)showInfo()string{
fmt.Println(“父类方法showInfo”)
message := fmt.Sprintf(“我的名字:%v 我的年龄:%v”,p.Name, p.Age)
return message
}
// 定义父类方法
func (p People)whoami(){
fmt.Println(“我是谁:”, p.Name)
}

// 定义子类结构体
type Student struct{
People
notes string
}
// 定义子类发方法
func(s Student) showInfo()(message string){
// 子类的方法如果和父类同名,那么就必须参数和返回值都是一样的,否则就会报错
fmt.Println(“子类方法showInfo”)
message = fmt.Sprintf(“我的名字:%v 我的年龄:%v”, s.Name, s.Age)
fmt.Println(message)
return
}

func DemoJc(){
// 声明一个对象
fmt.Println(“------面向对象-继承------”)
var s1 = Student{People{“关关”, 19}, “前任2”}
message := s1.showInfo()
fmt.Println(message)
fmt.Println(“==重新设置新的名字:盈盈”)
s1.setName(“颖颖”)
message = s1.showInfo()
fmt.Println(message)
}
// 输出结果
------面向对象-继承------
子类方法showInfo
我的名字:关关 我的年龄:19
我的名字:关关 我的年龄:19
==重新设置新的名字:盈盈
子类方法showInfo
我的名字:颖颖 我的年龄:19
我的名字:颖颖 我的年龄:19


#### 1.7.3多继承


多继承就是按照1.7.2的介绍,这个时候多加几个嵌入结构体就行了



type People struct{
Name string
Age int
}

type People2 struct{
Name string
Age int
higi int
}

type Student struct{
People
People2
notes string
}

func DemoMain(){
var st = Student{People{“xxx”, 19}, People2{“xxx”, 21, 180}, “测试”}
}


完整代码



package mystudy
// 面向对象-继承
import “fmt”

/*
人父类
*/
// 定义父类结构体
type People struct{
Name string
Age int
}

func (p *People)setName(name string){
(*p).Name = name
}

// 定义父类方法
func (p People)showInfo()string{
fmt.Println(“父类方法showInfo”)
message := fmt.Sprintf(“我的名字:%v 我的年龄:%v”,p.Name, p.Age)
return message
}
// 定义父类方法
func (p People)whoami(){
fmt.Println(“我是谁:”, p.Name)
}

/*
父类:People2
*/
type People2 struct{
Name string
Age int
high int
}

/*
学生子类
*/

// 定义子类结构体
type Student struct{
People
People2
notes string
}
// 定义子类发方法
func(s Student) showInfo()(message string){
// 子类的方法如果和父类同名,那么就必须参数和返回值都是一样的,否则就会报错
fmt.Println(“子类方法showInfo”)
message = fmt.Sprintf(“我的名字:%v 我的年龄:%v”, s.People.Name, s.People2.Age)
fmt.Println(message)
return
}

func DemoJc(){
// 声明一个对象
fmt.Println(“------面向对象-继承------”)
var s1 = Student{People{“关关”, 19},People2{“关关2”, 20, 88}, “前任2”}
message := s1.showInfo()
fmt.Println(message)
fmt.Println(“==重新设置新的名字:盈盈”)
s1.setName(“颖颖”)
message = s1.showInfo()
fmt.Println(message)
}
//
------面向对象-继承------
子类方法showInfo
我的名字:关关 我的年龄:20
我的名字:关关 我的年龄:20
==重新设置新的名字:盈盈
子类方法showInfo
我的名字:颖颖 我的年龄:20
我的名字:颖颖 我的年龄:20


注意:


1. 如果父类的属性有重复的,这个时候调用属性的时候要指定具体的结构体



s1.People.Name
s1.People2.Age


#### 1.7.4注意事项


1. 结构体的嵌入匿名结构体可以是基本类型



type People struct{
Name string
Age int
}

type Studen struct{
People
int
float32
}

st2 := Student2{People{“学生2”, 22}, 18,19}
fmt.Println(st2)
fmt.Println(st2.int)
fmt.Println(st2.float32)
// 输出结果
{{学生2 22} 18 19}
18
19


2. 创建结构体的时候可以使用之前的声明方法,使用key或者直接按照顺序



st3 := Student2{
People:People{
Name:“学生3”,
Age:22,
},
int:19,
float32:99,
}
fmt.Println(st3)
注意,最后要加上 逗号


3. 对于指针结构体嵌入引用的也是类似2的声明



package mystudy
// 面向对象-继承
import “fmt”

type Student3 struct{
*People
int
}

func DemoJc(){
st4 := Student3{
&People{“李华”, 22}, 88,
}
fmt.Println(st4)
fmt.Println(st4.People)
fmt.Println(*(st4.People))
}
// 输出结果
{0xc000116030 88}
&{李华 22}
{李华 22}


4. 结构体的字段可以是结构体的类型,这个在1.6章节介绍了。这通常也称为组合模式



type People struct{
Name string
}

type Student struct{
p People
}


## 1.8实现接口


#### 1.8.1语法定义


1. 接口语法:接口只能定义方法,不能定义变量



type Persion interface{
// 方法
eat()
// 方法
say()
}


2. 继承接口



type Student struct{

}
// 实现方法
func(s Student) eat(){
fmt.Println(“eat”)
}


#### 1.8.2注意事项


1. 接口中定义一组方法,但是不需要实现,不需要方法体,接口不能包含任何变啊零。
2. 实现接口要实现所有的方法才是实现,一下代码没有全部实现会报错



type Persion1 interface {
SayHello()
eat()
}
// 定义学生类
type StudentClass01 struct{
Name string
}

func(s StudentClass01) SayHello(){
fmt.Println(s, “Student say hello”)
}

当你调用的时候这里就会报错,如果没有全部实现编译不会报错
var st StudentClass01
var p Persion1
p = st
p.SayHello()

goproject\src\com\gdzs\mystudy\18.接口01.go:33:5: cannot use st (variable of type StudentClass01) as Persion1 value in assignment: StudentClass01 does not implement Persion1 (missing method SayHello)


3. Golang中的接口不需要显式的实现接口,Golang中没有implement关键字(Go中实现接口是基于方法的,不是基于接口的)
4. 如果有两个接口 A B 有共同的方法 a b 如果c结构体实现了a b两个方法,那么就是两个接口都实现了 如下的Persion1 和Persion两个接口



package mystudy
// 接口定义
import “fmt”

type Persion interface {
SayHello()
}

type Persion1 interface {
SayHello()
}
// 定义学生类
type StudentClass01 struct{
Name string
}

func(s StudentClass01) SayHello(){
fmt.Println(s, “Student say hello”)
}
// 定义教师类
type Teacher struct{
}

func(t Teacher) SayHello(){
fmt.Println(t, “Teacher say hello”)
}

func say(p Persion1){
p.SayHello()
}

func DemoInterface01(){
var st StudentClass01
var t Teacher
say(st)
say(t)
}


5. 接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量:这里说的其实就是面向对象的多态



// 定义教师类
type Teacher struct{
}

func(t Teacher) SayHello(){
fmt.Println(t, “Teacher say hello”)
}

func say(p Persion1){
p.SayHello()
}

func DemoInterface01(){
var t Teacher
say(t)
}


6. 只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型



type Persion1 interface{
SayHello()
}

func say(p Persion1){
p.SayHello()
}
// 其他类型的接口
type integer int

func (i integer)SayHello(){
fmt.Println(“int say hello:”, i)
}

func DemoInterface01(){
var i integer =100
say(i)
}
// 打印结果
int say hello:100


7. 一个自定义类型可以实现多个接口:同一个模块下的接口可以直接使用,比如这里的Persion使用的就是前面代码模块里面的



package mystudy
import “fmt”
// 实现多个接口
// 接口1
type Persion2 interface{
eat()
}
// 接口2
type Animal2 interface{
say()
}
// 结构体实现
type Student6 struct{

}
// 实现接口1
func(s Student6)eat(){
fmt.Println(“student eat”)
}
// 实现接口2
func(s Student6)say(){
fmt.Println(“student say”)
}

// 实现接口2
func(s Student6) SayHello(){
fmt.Println(“Student say hello”)
}
func DemoMulInterface(){
var st Student6
var p2 Persion2
// 前面代码模块里面的
var p1 Persion
var a Animal2
p2 = st
a = st
p1 = st
p2.eat()
a.say()
p1.SayHello()
}
// 输出结果
student eat
student say
Student say hello


8. 接口可以继承别的接口,A继承B ,那么实现的时候要都实现所有接口的方法才可以  
 #GO接口继承



package mystudy
// 接口继承接口
import “fmt”

type Ainter interface{
a()
}
type Binter interface{
b()
}
type Cinter interface{
Ainter
Binter
c()
}

type Dstruct struct{

}

func (s Dstruct) a(){

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

say(){
fmt.Println(“student say”)
}

// 实现接口2
func(s Student6) SayHello(){
fmt.Println(“Student say hello”)
}
func DemoMulInterface(){
var st Student6
var p2 Persion2
// 前面代码模块里面的
var p1 Persion
var a Animal2
p2 = st
a = st
p1 = st
p2.eat()
a.say()
p1.SayHello()
}
// 输出结果
student eat
student say
Student say hello


8. 接口可以继承别的接口,A继承B ,那么实现的时候要都实现所有接口的方法才可以  
 #GO接口继承



package mystudy
// 接口继承接口
import “fmt”

type Ainter interface{
a()
}
type Binter interface{
b()
}
type Cinter interface{
Ainter
Binter
c()
}

type Dstruct struct{

}

func (s Dstruct) a(){

[外链图片转存中…(img-EYmH7Bok-1715561143893)]
[外链图片转存中…(img-XSPLpjnn-1715561143893)]
[外链图片转存中…(img-fVHpj4hW-1715561143894)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值