• 3Golds
    2019-03-21
    建议老师不要总用java来讲
    
     24
  • Mao
    2019-03-31
    感谢老师用 Java 来讲, Java 程序员秒懂
    
     21
  • 谁都别拦着我
    2019-04-03
    把参数从interface指针换成interface就可以了,但是之前说的传指针是一种好习惯可以避免对象的拷贝,所以很不理解这里为什么用interface指针就不可以

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

    
     2
  • Geek_669c0b
    2019-06-11
    接口是定义多个对象之间交互的协议?不是太懂,这个有点蒙,老师能不能再稍微解释一下,接口对我们开发有什么指导意义吗?为什么要有接口呢,我只是知道接口定义了类的行为,必须实现哪些动作才能实现这个接口,这样有什么意思吗?还是不懂,望老师指点

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

    
     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
  • 风骑
    2020-01-17
    有个问题,老师,如果我用多个方法去实现这个接口函数的话,如下面的例子:
    package interface_test

    import "testing"

    type Programmer interface {
        WriteHelloWorld() string
    }

    type GoProgrammer struct {

    }

    type GoSecProgrammer struct {

    }

    func (g *GoProgrammer) WriteHelloWorld() string {
        return "fmt.Println(\"Hello World\")"
    }

    func (g *GoSecProgrammer) WriteHelloWorld() string {
        return "fmt.Println(\"Hello World,too\")"
    }

    func TestClient(t *testing.T) {
        var p Programmer
        p = new(GoProgrammer)

        t.Log(p.WriteHelloWorld())

        var g Programmer
        g = new(GoSecProgrammer)

        t.Log(g.WriteHelloWorld())
    }
    那这个就算是重载了吧
    展开

    作者回复: 你想说的是override吧,是指子类覆盖父类的方法,至于overload是指同一个类中方法名相同,但参数不同的方法。
    上面代码,并不属于这些,只是同一接口的不同实现。

    
    
  • iMARS
    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
    
  • Alien
    2019-09-01
    作为 PHPer 总用java来讲我也很懵啊

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

    
    
  • Geek_669c0b
    2019-06-12
    关于接口的作用,我又想了想,我的理解是,接口规定了一组约束,来一个实例,框架中都有关于缓存的实现,接口定义了缓存的使用行为,屏蔽了底层是基于redis还是memcache还是其他的缓存引擎,这样我们在业务层,就不用考虑底层的具体实现,因为他们一定实现了这些方法,所以说接口是多个对象之间交互的协议,我这么理解对吗?
    
    
  • kubernetes
    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定义一个别名其实没有影响的,只是看需不需要就好了。
    展开
    
    
  • 谁都别拦着我
    2019-04-03
    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
    
我们在线,来聊聊吧