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 {
    	...
    }
相关推荐
蒙娜丽宁2 天前
Go语言错误处理详解
ios·golang·go·xcode·go1.19
qq_172805593 天前
GO Govaluate
开发语言·后端·golang·go
littleschemer3 天前
Go缓存系统
缓存·go·cache·bigcache
程序者王大川4 天前
【GO开发】MacOS上搭建GO的基础环境-Hello World
开发语言·后端·macos·golang·go
Grassto4 天前
Gitlab 中几种不同的认证机制(Access Tokens,SSH Keys,Deploy Tokens,Deploy Keys)
go·ssh·gitlab·ci
高兴的才哥5 天前
kubevpn 教程
kubernetes·go·开发工具·telepresence·bridge to k8s
少林码僧6 天前
sqlx1.3.4版本的问题
go
蒙娜丽宁6 天前
Go语言结构体和元组全面解析
开发语言·后端·golang·go
蒙娜丽宁6 天前
深入解析Go语言的类型方法、接口与反射
java·开发语言·golang·go
三里清风_6 天前
Docker概述
运维·docker·容器·go