下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者
当前播放: 16 | Go语言的相关接口
00:00 / 00:00
标清
  • 标清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看

Go语言从入门到实战

共55讲 · 55课时,约700分钟
6092
免费
01 | Go语言课程介绍
免费
02 | 内容综述
免费
03 | Go语言简介:历史背景、发...
免费
04 | 编写第一个Go程序
免费
05 | 变量、常量以及与其他语言...
06 | 数据类型
07 | 运算符
08 | 条件和循环
09 | 数组和切片
10 | Map声明、元素访问及遍历
11 | Map与工厂模式,在Go语言...
12 | 字符串
13 | Go语言的函数
14 | 可变参数和defer
15 | 行为的定义和实现
16 | Go语言的相关接口
17 | 扩展与复用
18 | 不一样的接口类型,一样的...
19 | 编写好的错误处理
20 | panic和recover
21 | 构建可复用的模块(包)
22 | 依赖管理
23 | 协程机制
24 | 共享内存并发机制
25 | CSP并发机制
26 | 多路选择和超时
27 | channel的关闭和广播
28 | 任务的取消
29 | Context与任务取消
30 | 只运行一次
31 | 仅需任意任务完成
32 | 所有任务完成
33 | 对象池
34 | sync.pool对象缓存
35 | 单元测试
36 | Benchmark
37 | BDD
38 | 反射编程
39 | 万能程序
40 | 不安全编程
41 | 实现pipe-filter framew...
42 | 实现micro-kernel frame...
43 | 内置JSON解析
44 | easyjson
45 | HTTP服务
46 | 构建RESTful服务
47 | 性能分析工具
48 | 性能调优示例
49 | 别让性能被锁住
50 | GC友好的代码
51 | 高效字符串连接
52 | 面向错误的设计
53 | 面向恢复的设计
54 | Chaos Engineering
55 | 结束语
本节摘要
展开

精选留言(11)

  • 2019-03-31
    感谢老师用 Java 来讲, Java 程序员秒懂
    20
  • 2019-03-21
    建议老师不要总用java来讲
    19
  • 2019-06-11
    接口是定义多个对象之间交互的协议?不是太懂,这个有点蒙,老师能不能再稍微解释一下,接口对我们开发有什么指导意义吗?为什么要有接口呢,我只是知道接口定义了类的行为,必须实现哪些动作才能实现这个接口,这样有什么意思吗?还是不懂,望老师指点

    作者回复: 通常先定义两个模块交互的方法,这些方法定义在接口里。然后,模块都依赖于接口。各模块的分别实现自己的,接口就像协议。

    1
  • 把参数从interface指针换成interface就可以了,但是之前说的传指针是一种好习惯可以避免对象的拷贝,所以很不理解这里为什么用interface指针就不可以

    作者回复: 之所以穿指针是为了数据复制,interface是协议定义并不包含数据

    1
  • 2019-03-15
    老师您好,结合之前的知识点:go不支持隐式类型转换,我有些疑问,我的代码如下,也是我思考问题的思路:

    代码块1:
    type MyInt int
    func myFunc(op int) MyInt {
           // 明显,go不支持隐式类型转换,所以编译是不会通过的
        return op
    }

    代码块2:
    // 原始代码
    func timeSpent(inner func(op int) int) func(op int) int {
        return func(n int) int {
            start := time.Now()
            ret := inner(n)
            fmt.Println("time spent: ", time.Since(start).Seconds())
            return ret
        }
    }

    type IntConv func(op int) int
    // 改良代码1
    func timeSpent1(inner IntConv) IntConv {
           // 我总觉得这里就是一种隐式转换
          // 但是函数不是数据类型,所以不受隐式类型转换规则的约束
        return func(n int) int {
            start := time.Now()
            ret := inner(n)
            fmt.Println("time spent: ", time.Since(start).Seconds())
            return ret
        }
    }

    // 改良代码2
    func timeSpent2(inner IntConv) IntConv {
           // 于是,我想到了一种算是“显示”转换的方式,代码如下:
        intConv := *new(IntConv)
        intConv = func(op int) int {
            start := time.Now()
            ret := inner(op)
            fmt.Println("time spent: ", time.Since(start).Seconds())
            return ret
        }
        return intConv
    }

    我的疑问在于:
    1. 我对显示转换和隐式转换的理解是否有误,如果有误的话,是错在哪里了?
    2. timeSpent1和timeSpent2函数都实现了原有功能,只是实现方式不同,那么它们更深层次的区别是什么,比如是不是会有额外的内存消耗之类的?

    提问完毕,期待老师的解答,谢谢。
    展开

    作者回复: 这里是方法类型的定义,就像你定义struct,这里不是类型转化。
    至于性能和消耗,接下我的课程会讲如何benchmark代码,留给你自己实验分析得出结论,并分享给大家

    1
  • 2019-09-20
    //定义一个抽象的动物类接口
    type IAnimal interface {
        Say(msg string) string
    }

    type Duck struct {
        Name string
    }

    type Dog struct {
        Name string
    }

    func (duck *Duck) Say(msg string) string {
        return fmt.Sprintf("duck duck! my name is %s,%s", duck.Name, msg)
    }

    func (dog *Dog) Say(world string) string {
        return fmt.Sprintf("wang wang! my name is %s,%s", dog.Name, msg)
    }

    func TestAnimal(t *testing.T) {
        dog1 := Dog{Name: "Kitty"}
        var zoo = make([]IAnimal, 10, 20)
        animal := append(zoo, dog1)
          t.Log(animal)
    }

    为何最后两句会报 cannot use dog1 (type Dog) as type IAnimal in append:
        Dog does not implement IAnimal (Say method has pointer receiver)
    求指点!谢谢。
    展开

    作者回复: 这里要用指针才行:    animal := append(zoo, &dog1)

    1
  • 2019-09-01
    作为 PHPer 总用java来讲我也很懵啊

    作者回复: 不用担心,多看看我给的例子,多改多试

  • 2019-06-12
    关于接口的作用,我又想了想,我的理解是,接口规定了一组约束,来一个实例,框架中都有关于缓存的实现,接口定义了缓存的使用行为,屏蔽了底层是基于redis还是memcache还是其他的缓存引擎,这样我们在业务层,就不用考虑底层的具体实现,因为他们一定实现了这些方法,所以说接口是多个对象之间交互的协议,我这么理解对吗?
  • 2019-04-28
    go语言接口的实现是不依赖于接口的定义的,使用的是鸭子类型的方式的
  • 2019-04-05
    接着我上面的提问,做了benchamark:
    代码如下:
    package customertype

    import (
        "testing"
        "time"
    )

    func BenchmarkTimeSpent(b *testing.B) {
        b.ResetTimer()
        for i := 0; i < b.N; i++ {
            timeSpent(func(op int) int {
                time.Sleep(time.Second * 1)
                return op
            })
        }
        b.StopTimer()
    }

    func BenchmarkTimeSpent1(b *testing.B) {
        b.ResetTimer()
        for i := 0; i < b.N; i++ {
            timeSpent1(slowFun)
        }
        b.StopTimer()
    }

    func BenchmarkTimeSpent2(b *testing.B) {
        b.ResetTimer()
        for i := 0; i < b.N; i++ {
            timeSpent2(slowFun)
        }
        b.StopTimer()
    }

    结果:
    Running tool: /usr/local/go/bin/go test -benchmem -run=^$ ch11/customer_type -bench ^(BenchmarkTimeSpent|BenchmarkTimeSpent1|BenchmarkTimeSpent2)$ -v -cover

    goos: darwin
    goarch: amd64
    pkg: ch11/customer_type
    BenchmarkTimeSpent-4     50000000     32.8 ns/op     16 B/op     1 allocs/op
    BenchmarkTimeSpent1-4     50000000     32.3 ns/op     16 B/op     1 allocs/op
    BenchmarkTimeSpent2-4     50000000     33.4 ns/op     16 B/op     1 allocs/op
    PASS
    coverage: 0.0% of statements
    ok     ch11/customer_type    5.043s
    Success: Benchmarks passed.

    反复做了几次之后,发现效率其实并没有本质的区别,单个操作所占的内存也都是一样的。所以应该是我想太多了,有没有给func(op int) int定义一个别名其实没有影响的,只是看需不需要就好了。
    展开
  • type Programmer interface {
        WriteHW() string
    }

    type GoProgrammer struct {
    }

    func write_sth(p *Programmer) string {
        return p.WriteHW()
    }

    这段代码在write_sth出错,报错为“p.WriteHW undefined (type *Programmer is pointer to interface, not interface)”
    请问下为什么不能使用一个interface的指针作为传入参数?
    我的目的是为了让所有实现了这个接口的struct都能用来调用这个write_sth函数
    展开

    作者回复: 改为func write_sth(p Programmer)

    2