学习疑惑: Golang 中接口的作用体现在哪里? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Deardrops
V2EX    Go 编程语言

学习疑惑: Golang 中接口的作用体现在哪里?

  •  
  •   Deardrops
    deardrops 2018-09-28 16:56:46 +08:00 6984 次点击
    这是一个创建于 2659 天前的主题,其中的信息可能已经有所发展或是发生改变。

    初学 Golang,对于接口部分有一些不太理解的地方,希望 V 友能帮忙解答一下。

    package main import "fmt" type Stringer interface { String() string } type Printer interface { Stringer // 接口嵌入。 Print() } type User struct { id int name string } func (self *User) String() string { return fmt.Sprintf("user %d, %s", self.id, self.name) } func (self *User) Print() { fmt.Println(self.String()) } func main() { var t Printer = &User{1, "Tom"} // *User 方法集包含 String、Print。 // 如果去掉接口定义的代码,将上一行代码替换为下行,也可以运行,请问接口的作用体现在哪里? // var t := User{1, "Tom"} t.Print() } 

    以上代码摘录自Go 边看边练 -《 Go 学习笔记》系列(十二)

    书上写了接口声明一个方法的签名。声明一个空方法集的接口类型,并将其作为函数参数,函数不会检查传入的是什么类型,只要这个参数满足接口定义即可,即可以通过编译器检查(个人理解)。另外,接口可以进行接口检查,接口嵌入等。我学到了这些理论知识,但对接口缺乏感性的认识。

    相对于不定义接口,「直接定义结构体和结构体上的方法」的方式,额外定义了接口会带来什么好处么?

    可以举几个实际的例子么?

    11 条回复    2018-09-30 14:11:57 +08:00
    gowk
        1
    gowk  
       2018-09-28 17:12:15 +08:00   1
    接口跟语言无关,无非是为了抽象,具体说就是为了解耦,隔离变化。Go 语言中的接口跟 Java 中的大同小异,最大的区别就是 Go 语言的 Interface 是 Duck Typing,无侵入式的,另外我建议你不要用这个教程学习 Go 语言,教程里的例子为了举例而举例,对初学者而言完全没有任何意义。英文好的话直接看英文教程,推荐两本书,《 The Go Programming Language 》《 The Way To Go 》,英语对于程序员的重要性再怎么强调都不为过!
    gowk
        2
    gowk  
       2018-09-28 17:15:44 +08:00
    上面两本电子书找不到的话,可以访问我的百度网盘分享链接: https://pan.baidu.com/s/1mic0v00
    里面有很多经典的计算机类的 PDF 电子书
    imnotfine
        3
    imnotfine  
       2018-09-28 17:20:25 +08:00   2
    其实面向对象的问题.

    如果你初学编程的话, 我非常建议你跳过这部分, 因为需要你做一些项目才能理解其作用 ,特别是需要多人合作的项目

    ------

    举个栗子, 如果你写了一个类, 一年后你对这个类不满意, 你想重新实现一个, 那为了保证兼容性, 你肯定不能完全写个新的对吧.

    那你肯定要理清这个类提供了哪些公开的 api, 那你就得到了一个接口

    然后根据这些 api 去实现一个新的类, 然后用这个新的类去替换旧代码.

    -------

    下面是更好的方案

    那其实更好的方式是, 在刚开始写这个类的时候就想好这个类可以提供哪些方法, 然后定义一个接口, 然后一年后你写个新的, 你直接实现这个接口就好了, 而不用理清. 另外, 试想, 如果写这个新类的人是你同事, 让他去理清这些公开 api, 他应该会很头疼, 甚至直接放弃这个需求了吧.

    ------

    除了修改和重构上的方便外, 对调用方来说也是非常重要的, 这个涉及到多态, 然后你联想一下设计模式, 还有为什么允许`var t Printer = &User{1, "Tom"}`, 甚至推荐这种用法, 这就是你要思考的问题啦~
    Deardrops
        4
    Deardrops  
    OP
       2018-09-28 17:23:20 +08:00
    @gowk #1 感谢解答。正在看这两本书,看到接口的部分看不大明白,谷歌到的一个解释接口的文章,顺手贴出来了。书中说,Golang 语言中接口和满足接口的类型之间没有显式的连接,有时有的自定义类型可以同时满足多个接口,使用起来不会带来困惑么?
    neoblackcap
        5
    neoblackcap  
       2018-09-28 17:27:24 +08:00   2
    @Deardrops 这就是语言的哲学,也是面向对象的进一步理解。面向对象应该基于协议,接口。组合优先于继承,既然满足了接口,那么就应该认为这里的对象就是一类。
    Deardrops
        6
    Deardrops  
    OP
       2018-09-28 17:28:49 +08:00
    @imnotfine #3 感谢解答。之前写过一些 JS,对 OOP 一直没啥概念,听了你的解释明白了很多东西。谢谢!
    tourist2018
        7
    tourist2018  
       2018-09-28 17:38:15 +08:00
    golang 的接口就是一系列方法的集合
    misaka19000
        8
    misaka19000  
       2018-09-28 17:44:51 +08:00
    我也是在了解了 golang 的接口之后才对计算机里面的指令和数据有了更进一步的了解
    gamexg
        9
    gamexg  
       2018-09-28 20:58:03 +08:00   1
    实际使用下 go 的压缩、加密库就能够理解接口的作用了。
    加密、压缩传入 Writer 接口,输出的还是兼容 Writer,只要需求方实现了 Write 方法都能使用,不用管是文件还是连接。
    owenliang
        10
    owenliang  
       2018-09-29 09:52:39 +08:00
    面向接口编程啊,无论是过程式的还是对象式的,都可以实现接口和实现的分离。
    hijoker
        11
    hijoker  
       2018-09-30 14:11:57 +08:00
    感觉卵用没有,没有默认的接口实现
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2929 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 00:29 PVG 08:29 LAX 16:29 JFK 19:29
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86