// day03
package main
import (
"fmt"
)
//defer
// 3 4 2 1(
// 延迟执行-----先进后出
func defer1() {
defer fmt.Println("1") //延迟执行的函数
defer fmt.Println("2") //延迟执行的函数
fmt.Println("3")
fmt.Println("4")
}
//defer 后的函数使用变量的情况
func defer2() {
var a int = 10
defer fmt.Println(a) //10 延迟执行——虽然延迟执行,但在编译的时候就已经确定了。
a++
fmt.Println(a)
}
//defer 调用的函数参数的值在defer 被定义时就确定了
//而defer 函数内部所使用的变量的值是在这个函数执行的时候才确定。
func defer3() {
var a int = 10
defer func() { //延迟执行
fmt.Println(a) // 11
}()
a++
fmt.Println(a)
}
//defer 函数调用的执行时机是外层函数设置返回值之后,并且在即将返回之前。
func double(x int) int {
return x + x
}
func triple(x int) (r int) {
defer func() {
r += x
}()
return double(x)
}
//panic 和recover 函数的演示
func foo() {
defer func() {
fmt.Println("deferfunc_start")
//程序从异常中恢复。
if err := recover(); err != nil {
fmt.Println(err)
}
fmt.Println("deferfunc_end")
}()
fmt.Println("foo.start")
panic("foo 函数中产生的异常")
fmt.Println("foo.end")
}
//1 结构体的声明
type Person struct {
Name string
Age int
}
func structDemo() {
//结构体的定义和初始化的三种方法
p1 := Person{}
p1.Name = "张三"
p1.Age = 18
fmt.Println(p1)
p2 := Person{"李四", 20}
fmt.Println(p2)
p3 := Person{Age: 25, Name: "王五"}
fmt.Println(p3)
}
//2 匿名组合(实现继承)
type Student struct {
Person
Major string
}
func Inherit() {
s1 := Student{Person{"张飞", 18}, "计算机应用"}
fmt.Println(s1)
fmt.Println(s1.Name)
fmt.Println(s1.Person.Name)
fmt.Println(s1.Age)
fmt.Println(s1.Major)
//3 匿名组合的重名问题
// s2 := Student{Person{"张飞", 18}, "计算机应用", "李四"}
//fmt.Println(s2)
}
//3 匿名组合的重名问题
type Base1 struct {
Name string
}
type Base2 struct {
Name string
}
//Child 继承了Base1和Base2
type Child struct {
Base1
*Base2
Name string
}
func ManyInherit() {
c1 := Child{Base1{"base1"}, &Base2{"base2"}, "child"}
fmt.Println(c1)
fmt.Println(c1.Name)
fmt.Println(c1.Base1.Name)
fmt.Println(c1.Base2.Name)
}
//4 匿名结构体
func AnonymousStruct() {
s := struct {
Name string
Age int
}{
"张三",
18,
}
fmt.Println(s)
}
//5 空结构体
func EmptyStruct() {
empty := struct{}{}
fmt.Println(empty)
}
// 方法:
//1 66行,为Person 这个类型增加方法,接收器为类型Person,
// this Person 这个就是接收器
func (this Person) ShowInfo() {
fmt.Printf("姓名:%s\n年龄:%d\n", this.Name, this.Age)
}
func WayDemo() {
p1 := Person{"张三", 18}
p1.ShowInfo()
//2类型指针作为接收器演示
p1.SetName(" 张三丰")
p1.SetAge(100)
p1.ShowInfo()
}
//2 类型指针作为接收器。引用传递才可以修改引用对象的值。
func (p *Person) SetName(name string) {
p.Name = name
//等价于(*p).Name = name
}
func (this *Person) SetAge(age int) {
this.Age = age
}
//对子类进行添加方法
//3 接收器是类型指针
func (ps *Student) SetMajor(major string) {
ps.Major = major
}
func (s Student) ShowInfo() {
fmt.Printf("姓名:%s\n年龄:%d\n专业:%s\n",
s.Name, s.Age, s.Major)
}
func StudentTool() {
a1 := Student{Person{"张三", 18}, "计算机应用"}
//调用Student类型的ShowInfo方法
a1.ShowInfo()
//调用Person类型的ShowInfo方法
a1.Person.ShowInfo()
a1.SetName("张三丰")
a1.SetAge(100)
a1.SetMajor("太极拳")
a1.ShowInfo()
}
// 4 方法值和方法表达式
type Integer int //某个对象
func (i Integer) Add(j Integer) Integer { //某个对象的方法
return i + j
}
func Way() {
var a Integer
var b Integer
//对象的方法,称为方法值
fmt.Println(a.Add(100))
//
add := b.Add
fmt.Println(add(100))
//2 类型的方法,称为方法表达式
add2 := Integer.Add //类型的方法就是方法表达式
fmt.Println(add2(100, 200)) //但第一个参数作为接收器。
fmt.Println(Integer.Add(100, 200))
}
//六
//.
//接
//口
//演
//示
//定义一个接口
type IPhone interface {
Call()
}
//定义类型实现接口
type DumbPhone struct {
Name string
}
func (d DumbPhone) Call() {
fmt.Println("使用" + d.Name + "打电话...")
}
func InterfaceDemo() {
//1 将一个对象赋值给一个接口
var phone IPhone //1.定义了一个接口
phone = DumbPhone{"诺基亚非智能机"} //2.将一个对象赋值给一个接口
phone.Call() //3.直接使用接口调用函数
//2 将对象地址赋值给一个接口
pDumbPhone := &DumbPhone{"非智能机"}
pDumbPhone.Call()
}
// 相机接口
type ICamera interface {
TakePicture()
}
type DigitalCamera struct {
Name string
}
func (d DigitalCamera) TakePicture() {
fmt.Println("使用" + d.Name + "照相")
}
func Camera() {
var ic ICamera
ic = &DigitalCamera{"佳能数据相机"}
ic.TakePicture()
}
//一个接口赋值给另一个接口
type IPhoneCamera interface {
IPhone
ICamera
}
type ICameraPhone interface {
TakePicture()
Call()
}
//以上两个接口IPhoneCamera 和 ICameraPhone 是等价的。
//方法列表相同(次序可以不同),那么这两个接口可以相互赋值
//实现 IPhoneCamera 接口
type SmartPhone struct {
Name string
}
func (sp SmartPhone) Call() {
fmt.Println("使用" + sp.Name + "打电话...")
}
func (sp SmartPhone) TakePicture() {
fmt.Println(" 使用" + sp.Name + "照相...")
}
func UseSmartPhone() {
var ipc IPhoneCamera
ipc = &SmartPhone{"华为智能机"}
ipc.TakePicture()
ipc.Call()
//将一个接口赋值给另一个接口
//两个等价接口的赋值
var icp ICameraPhone
icp = ipc
icp.Call()
icp.TakePicture()
//由大到小的接口赋值(小接口 = 大接口 父类 = 子类 )
var ip IPhone
ip = ipc
ip.Call()
fmt.Println("")
fmt.Println(ip.(ICameraPhone))
if v, ok := ip.(ICameraPhone); ok {
fmt.Println("-----接口查询-----")
v.Call()
v.TakePicture()
fmt.Println("-----接口查询-----")
} else {
fmt.Println("ip 接口操作对象没有实现 icp 接口")
}
}
//空接口演示
func emptyInterface() {
//使用空接口可以直接接受任何基本类型
var object interface{}
object = 10
fmt.Println(object)
object = "ten"
fmt.Println(object)
object = 10.25
fmt.Println(object)
//使用空间口接收自定义类型
sp := SmartPhone{"华为智能机"}
sp.Call()
object = sp
// object = SmartPhone{"华为智能机"}
switch v := object.(type) { //固定写法
case int:
fmt.Println("int 类型", v)
case string:
fmt.Println("string 类型", v)
case float64:
fmt.Println("float64 类型", v)
case SmartPhone:
fmt.Println("SmartPhone", v)
default:
fmt.Println("未知类型", v)
}
}
//使用空接口作为函数的参数
func CallWithInterface(i interface{}) {
if v, ok := i.(IPhone); ok {
v.Call()
}
if v, ok := i.(ICamera); ok {
v.TakePicture()
}
//switch v:=i.(type)
}
func Call() {
phone := DumbPhone{"诺基亚"}
CallWithInterface(phone)
camera := DigitalCamera{"佳能"}
CallWithInterface(camera)
}
func main() {
Call()
// emptyInterface()
// UseSmartPhone()
// Camera()
// InterfaceDemo()
// 方法值和方法表达式
// Way()
// StudentTool()
// WayDemo()
// EmptyStruct()
// AnonymousStruct()
// ManyInherit()
// Inherit()
// structDemo()
// fmt.Println(" 程序开始执行...")
// foo()
// fmt.Println(" 主程序执行中...")
// fmt.Println(" 程序执行结束...")
// fmt.Println(triple(3)) //defer3()
// defer2()
// defer1()
}
go语言学习第三天
最新推荐文章于 2023-06-05 15:33:49 发布