Go语言学习04~05 函数和面向对象编程

Go语言学习04-函数

函数是一等公民

<font color="Blue">与其他主要编程语言的差异</font>

  1. 可以有多个返回值
  2. 所有参数都是值传递: slice, map, channel 会有传引用的错觉
  3. 函数可以作为变量的值
  4. 函数可以作为参数和返回值

学习函数式编程

可变参数

go 复制代码
func sum(ops ...int) int {
    s := 0
    for _, op := range ops {
        s += op
    }
    return s
}

defer 函数

go 复制代码
func TestDefer(t *testing.T) {
    defer func() {
        t.Log("Clear resources")
    }()
    t.Log("Started")
    panic("Fatal error") // defer仍会执行
}

Go语言学习05-面向对象编程

Go语言官方对于Go 语言是否为面向对象编程的描述https://golang.org/doc/faq

Is Go an object-oriented language?

Yes and no. Although Go has types and methods and allows an object-oriented style of programming, there is no type hierarchy. The concept of "interface" in Go provides a different approach that we believe is wasy to use and in some ways more general.

Also, the lack of a type hierarchy makes "objects" in Go fell much more lightweight than in language such as C++ or Java.

封装数据和行为

结构体定义
go 复制代码
type Employee struct {
    Id string
    Name string
    Age int
}
实例创建及初始化
go 复制代码
e := Employee{"0", "Bob", 20}
e1 := Employee{Name: "Mike", Age:30}
e2 := new(Employee)		// 注意这里返回的引用/指针, 相当于 e:=&EmployeeP{}
e2.Id = "2"				// 与其他编程语言的差异: 通过实例的指针访问成员不需要->
e2.Age = 22
e2.Name = "Rose"
行为 (方法) 定义
go 复制代码
// 第一种定义方式在实例对应方法被调用时, 实例的成员会进行值复制
func (e Employee) String() string {
    return fmt.Sprintf("ID:%s-Name:%s-Age:%d", e.Id, e.Name, e.Age)
}

// 通常情况下为了避免内存拷贝我们使用第二种定义方式
func (e *Employee) String() string {
    return fmt.Sprintf("ID:%s-Name:%s-Age:%d", e.Id, e.Name, e.Age)
}

接口与依赖

<<interface>> A AImpl AClient

java 复制代码
// Programmer.java
public interface Programmer {
    String WriteCodes();
}

// GoProgrammer.java
public class GoProgrammer implements Programmer{
    @Override
    public String WriteCodes() {
        return "fmt.Println(\"Hello World!\")";
    }
}

// Task.java
public class Task {
    public static void main(String[] args) {
        Programmer prog = new GoProgrammer();
        String codes = prog.WriteCodes();
        System.out.printlv(codes);
    }
}

Duck Type式接口实现

接口定义
go 复制代码
type Programmer interface {
    WriteHelloWorld() Code
}
接口实现
go 复制代码
type GoProgrammer struct {
}

func (p *GoProgrammer) WriteHelloWorld() Code {
    return "fmt.Printlv(\"Hello World!\")"
}

Go 接口

与其他主要编程语言的差异

  1. 接口为非入侵性, 实现不依赖于接口定义
  2. 所以接口的定义可以包含在接口使用者包内

接口变量

自定义类型

  1. type IntConvertionFn func(n int) int
  2. type Mypoint int

多态

空接口与断言

  1. 空接口可以表示任何类型

  2. 通过断言来将空接口转换为指定类型

    go 复制代码
    v, ok := p.(int)   //ok = true 时为转换成功

Go 接口最佳实践

  • 倾向于使用小的接口定义, 很多接口只包含一个方法

    go 复制代码
    type Reader interface {
        Read(p []byte) (n int, err int)
    }
    
    type Writer interface {
        Write(p []byte) (n int, err int)
    }
  • 较大的接口定义, 可以由多个小接口定义组合而成

    go 复制代码
    type ReadWriter interface {
        Reader
        Writer
    }
  • 只依赖于必要功能的最小接口

    go 复制代码
    func StoreData(reader Reader) error {
    	...
    }
相关推荐
一丝晨光3 天前
数值溢出保护?数值溢出应该是多少?Swift如何让整数计算溢出不抛出异常?类型最大值和最小值?
java·javascript·c++·rust·go·c·swift
陌尘(MoCheeen)4 天前
技术书籍推荐(002)
java·javascript·c++·python·go
白泽来了6 天前
字节大模型应用开发框架 Eino 全解(一)|结合 RAG 知识库案例分析框架生态
开源·go·大模型应用开发
致于数据科学家的小陈7 天前
Go 层级菜单树转 json 处理
python·go·json·菜单树·菜单权限·children
白总Server8 天前
Golang领域Beego框架的中间件开发实战
服务器·网络·websocket·网络协议·udp·go·ssl
ん贤8 天前
GoWeb开发
开发语言·后端·tcp/ip·http·https·go·goweb
纪元A梦9 天前
华为OD机试真题——荒岛求生(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
java·c语言·javascript·c++·python·华为od·go
chxii11 天前
3.2goweb框架GORM
go
42fourtytoo12 天前
从0开始建立Github个人博客(hugo&PaperMod)
运维·服务器·python·go·github
xuhe213 天前
[tldr] GO语言异常处理
go·error