Go语言又伸魔爪,汇编语言程序设计 pdf架的住吗

拒绝访问 | www.hackbase.com | 百度云加速
请打开cookies.
此网站 (www.hackbase.com) 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3deb05bae7365086-ua98).
重新安装浏览器,或使用别的浏览器Go语言又伸魔爪,汇编语言架的住吗?
近日有消息称,为改进Go语言,谷歌可能赋予Go语言类似于微软和Red Hat的语言服务器协议的语言服务器。消息是从Go语言开发者的讨论组中流出,但目前改进的主要方面还没有敲定。
这个开发团队的改进计划如下:
&采用语言服务器IDE等工具,索引、显示有关代码与包中的相关信息。微软的语言服务器协议支持广泛的编辑和IDE,而该协议被设计为跨代码编辑器和IDE集成的多种语言。
&建立可报告统计数据的标准&计数器&API
&重写部分Go的汇编代码
&重写Go的加密代码。出于性能考虑,以往语言中的加密代码主要用汇编语言编写,但汇编代码很难调试、维护和读取。改用Go重写加密代码会使维护更加容易。
&扩展Go1.9版本中math/bits包。math/bits包对位操作进行了优化,以适应重写。
&重构在编译器和运行时的垃圾收集和相关工具,减少内核和IDE的负载。
&将编译器嵌入到IDE中快速检查语法。
&编译内存代码。编译内存代码有利于修复缺少系统文件的环境,程序员还可以进行持续的运行测试。
除此之外,还有人提出依赖关系管理和接口问题。完美的依赖关系管理可能有助于软件包从标准库迁移到自己的项目中。但是标准库中的软件包修复需要较长的时间,大概6个月才能完成。
 您阅读这篇文章共花了: 
工具下载提示:
本文作者:找黑客    
文章标题:
本文地址:
版权声明:若无注明,本文皆为“找黑客网”原创,转载请保留文章出处。
 相关文章GO语言-接口0收藏分享举报{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\u002Fpay.zhihu.com\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[],&title&:&GO语言-接口&,&author&:&wang-wen-xue-3-2&,&content&:&\u003Cp\u003E#GO语言面向对象编程之接口(下)#\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003EGo's interfaces—static, checked at compile time, dynamic when asked for—are, for me, the most exciting part of Go from a language design point of view. If I could export one feature of Go into other languages, it would be interfaces. \u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E接口在GO语言的地位从上面作者的原话就可以看出来了,所以对于接口的学习,直接去读了一些英文的文献。下面的介绍,主要根据这篇文献来解释:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E& [\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fjordanorelli.com\u002Fpost\u002F\u002Fhow-to-use-interfaces-in-go\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Ejordanorelli.com\u002Fpost\u002F3\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u002Fhow-to-use-interfaces-in-go\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E](\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fjordanorelli.com\u002Fpost\u002F\u002Fhow-to-use-interfaces-in-go\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Ejordanorelli.com\u002Fpost\u002F3\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u002Fhow-to-use-interfaces-in-go\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E)\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Ci\u003E**\u003C\u002Fi\u003E*\u003C\u002Fp\u003E\u003Cp\u003E##接口的介绍\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E接口是什么?\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E接口包含两部分:接口是一组方法,但同时也是一种类型,首先我们从一组方法来解释。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E&font size = 5 color =red&we’ll define an Animal as being anything that can speak. This is a core concept in Go’s type system。 instead of designing our abstractions in terms of what kind of data our types can hold, we design our abstractions in terms of what actions our types can execute.&\u002Ffont&\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E这段话实在不知道怎么翻译才能翻译出精髓的含义。大体意思就是我们定义了一个Animal的接口,只要拥有说话功能的对象都是Aniamal。不再去设计我们可以拥有哪些类型的数据,而是去关注我们有哪些方法可以执行。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E我们设计的接口如下:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
type Animal interface {\u003C\u002Fp\u003E\u003Cp\u003E
Speak() string\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003ESpeak 函数没有参数,返回string类型。任何拥有Speak函数的类型都可以说实现了Animal接口。在Go语言里没有Implements关键字;一个数据类型是否实现接口自动决定,来看下面实现了接口的例子:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
type Dog struct {\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func (d Dog) Speak() string {\u003C\u002Fp\u003E\u003Cp\u003E
return \&Woof!\&\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
type Cat struct {\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func (c Cat) Speak() string {\u003C\u002Fp\u003E\u003Cp\u003E
return \&Meow!\&\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
type Llama struct {\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func (l Llama) Speak() string {\u003C\u002Fp\u003E\u003Cp\u003E
return \&?????\&\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
type JavaProgrammer struct {\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func (j JavaProgrammer) Speak() string {\u003C\u002Fp\u003E\u003Cp\u003E
return \&Design patterns!\&\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E在这里我们定义了四种类型,每种类型都拥有自己的Speak函数。所以四种类型都实现了接口Animal。所以我们可以直接创建一个Animal的slice然后看每个类型的输出:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func main() {\u003C\u002Fp\u003E\u003Cp\u003E
animals := []Animal{Cat{}, Dog{}, Llama{}, JavaProgrammer{}}\u003C\u002Fp\u003E\u003Cp\u003E
for _, animal := range animals {\u003C\u002Fp\u003E\u003Cp\u003E
fmt.Println(animal.Speak())\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Ci\u003E**\u003C\u002Fi\u003E*\u003C\u002Fp\u003E\u003Cp\u003E##interface{} 类型\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003Einterface{}是一个空的Interface,也是很容易产生疑惑的地方。因为空的interface没有任何的函数,又因为Go语言里面没有Implements关键字来标识接口的实现关系,所以所有的类型都可以认为是实现了interface{}.这意味着如果你定义了一个函数,函数参数是空的Interface的话,那么函数可以接受任意类型的参数。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func DoSomething(v interface{}) {\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F ...\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E函数DoSomething可以接受任何的参数,那么在函数里面v的数据类型是什么?因为前面说过interface{}可以被任意类型实现,所以有的人认为v是“任意类型”。事实上v是interface类型。GO在运行的过程中会做类型的转换,每一个变量在运行的时候都会有一个类型。这里的v就是interface{}类型。如果对上述的函数调用如下:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
data := []int{1, 2, 3, 4, 5}\u003C\u002Fp\u003E\u003Cp\u003E
DoSomeThing(data)\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E这时候编译有出现如下的错误:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
.\\main.go:48: cannot use data (type []int) as type []interface {} in argument to DoSomeThing\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E这里证明接口是一种类型,而不是所谓的“任意类型”。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E看到这里如果你还是疑惑的,那么是正常的,如果没任何的疑惑,那就再读一遍前面的东西,或者直接读上面的英文原文。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E**接口的由2个words组成:一个指向了接口中存数的数据类型,另外一个指向是该接口的方法列表,注意是该接口的,不是存放的数据类型的。**\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E![](\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=http%3A\u002F\u002Fi.imgur.com\u002F0tXStyB.png\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Ei.imgur.com\u002F0tXStyB.png\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E)\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E接口的实现可以参照这篇文章来看:\u003C\u002Fp\u003E\u003Cp\u003E[\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fresearch.swtch.com\u002Finterfaces\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Eresearch.swtch.com\u002Finte\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003Erfaces\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E](\u003Ca href=\&http:\u002F\u002Flink.zhihu.com\u002F?target=https%3A\u002F\u002Fresearch.swtch.com\u002Finterfaces\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\u003Eresearch.swtch.com\u002Finte\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003Erfaces\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fa\u003E)\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E对于开始的Animal的实例,我们发现我们定义的Animal接口切片的时候采用的如下的方式:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
animals := []Animal{Cat{}, Dog{}, Llama{}, JavaProgrammer{}}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E所以这里的Animal[0]里面的两个words一个指向是Cat这个变量,另外一个Words指向的是Animal这个接口的函数列表。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E但细心的人可能会发现,为什么我们没有进行任何的强制转化,比如Animal(Cat{})就可以直接将Cat变量存放到接口里面那,原因就是默认的进行了强制转化。所以我们不需要再对其进行强转。而对于上面的DoSomething的函数的调用,我们需要将切片显式的转化为切片类型才可以调用它,所以代码如下:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func DoSomeThing(v []interface{}) {\u003C\u002Fp\u003E\u003Cp\u003E
for _, data := range v {\u003C\u002Fp\u003E\u003Cp\u003E
fmt.Println(data)\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
data := []int{1, 2, 3, 4, 5}\u003C\u002Fp\u003E\u003Cp\u003E
value := make([]interface{}, len(data))\u003C\u002Fp\u003E\u003Cp\u003E
for i := 0; i & len(data); i++ {\u003C\u002Fp\u003E\u003Cp\u003E
value[i] = data[i]\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E
DoSomeThing(value)\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E这代码看起来很丑,但没有完美的东西。[]interface{}也并没有你想的那么经常的出现,因为它的作用并没有你一开始想的那么有用。(文章的原话,个人觉得真心丑o(╯□╰)o)。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E****\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E##Pointers and interfaces\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E关于接口的另外一个小技巧在于,接口定义并没有规定实现接口的接收者是指针还是类型。我们前面的Animal采用的都是类型作为接收者,如果把类型改为指针:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func (c *Cat) Speak() string {\u003C\u002Fp\u003E\u003Cp\u003E
return \&Meow!\&\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E编译会有以下错误:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
.\\main.go:41: cannot use Cat literal (type Cat) as type Animal in array or slice literal:\u003C\u002Fp\u003E\u003Cp\u003E
Cat does not implement Animal (Speak method has pointer receiver)\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E错误的意思就是你定义的函数Speak是一个指针作为接收者,但你是将一个Cat struct转换成为了Animal。所以你可以将初始化的地方变成指针如下:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
animals := []Animal{new(Cat), Dog{}, Llama{}, JavaProgrammer{}}\u003C\u002Fp\u003E\u003Cp\u003E
animals := []Animal{&Cat{}, Dog{}, Llama{}, JavaProgrammer{}}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E两种方法都可以使用。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E但如果我们将Speak()函数改为类型作为接收者,但用指针作为参数。就不会出现错误,因为指针可以解析到它关联的数据类型。代码如下:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func (c Cat) Speak() string {\u003C\u002Fp\u003E\u003Cp\u003E
return \&Meow!\&\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
animals := []Animal{new(Cat), Dog{}, Llama{}, JavaProgrammer{}}\u003C\u002Fp\u003E\u003Cp\u003E
animals := []Animal{&Cat{}, Dog{}, Llama{}, JavaProgrammer{}}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E这种情况看起来挺难理解的,前面的时候我们讲过:\u003Cb\u003E**everything in Go is passed by value. Every time you call a function, the data you’re passing into it is copied.**\u003C\u002Fb\u003E简单的理解就是,我们调用函数的时候参数都是拷贝的,所以你对形参做的操作在外面是看不到,因为形参只是实参的复制。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E再看一下我们前面说的两种情况:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E1.指针作为接收的时候只能用指针去调用。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E2.类型作为接收的时候可以用指针和类型去调用。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E下面的例子:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func (t T)MyMethod(s string) {\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F ...\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E函数MyMethod函数是func(T, string)类型,函数的接收者会和其它参数一样传入函数内部。所以对于第一种情况,先看看作者的解释:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003ESince everything is passed by value, it should be obvious why a \u003Ci\u003E*Cat method is not usable by a C any one Cat value may have any number of *\u003C\u002Fi\u003ECat pointers that point to it. If we try to call a \u003Ci\u003E*Cat method by using a Cat value, we never had a *\u003C\u002Fi\u003ECat pointer to begin with。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E意思是Cat 有很多指向它的指针,所以当你用cat 变量去调用*Cat的方法的时候,Cat指针不知道指向哪。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E对于第二种,是因为当你用指针Cat去调用Cat的时候,因为指针可以知道自己指向的地址,所以Go语言在运行的过程中会把\u003Ci\u003E*Cat去重新定义到它指向的变量。所以Go语言里面给个Dog类型的指针 *\u003C\u002Fi\u003Ed,我们可以直接调用d.Speaker,而不用像其它语言d-&Speaker。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E其实不懂的话就住:&font color = \&red\&&指针接收者的函数只能指针调用,但类型接收者的函数,指针和类型都可以调用&\u002Ffont&\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Ci\u003E**\u003C\u002Fi\u003E*\u003C\u002Fp\u003E\u003Cp\u003E##接口的应用-从http request里面得到对象\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E假设要设计一个接口来解决web开发问题,我们需要将http的request解析到一些对象里面(比如struct来提取自己想要的信息)。一开始的时候没有明确的设计,但知道的是需要得到一些数据资源从reques里面,所以一开始的设计如下:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
GetEntity(*http.Request) (interface{}, error)\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E返回Interface{},因为它可以代表任意的类型。但这的确不是一个很好的设计,因为对于不同的结构的话,我们都需要更改GetEntity函数。在GO语言里面有个不成文的规则:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E&font color = \&red\&&it’s typically better to take in an interface{} value as a parameter than it is to return an interface{} value. (Postel’s Law, applied to interfaces)&\u002Ffont&\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E或者可以设计成这种模式:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
GetUser(*http.Request) (User, error)\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E这样的话每一个类型的User都对应一个函数,虽然这样也可以实现,但会显得代码很难形成统一的概念。(可以理解代码不够优美,毕竟面向对象的语言,如果每个对象都对应自己的函数,没有统一的管理,那么代码的可读性和维护性都会很差),所以我们可以设计成:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
type Entity interface {\u003C\u002Fp\u003E\u003Cp\u003E
UnmarshalHTTP(*http.Request) error\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E
func GetEntity(r *http.Request, v Entity) error {\u003C\u002Fp\u003E\u003Cp\u003E
return v.UnmarshalHTTP(r)\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E这样的话 GetEntity 函数可以接收任意拥有UnmarshalHTTP函数的类型参数, 首先声明一个以User point作为接收者的UnmarshalHTTP函数。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
func (u *User) UnmarshalHTTP(r *http.Request) error {\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F ...\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E然后我们需要声明一个User的变量,然后讲其指针传递给函数GetEntity。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E
var u User\u003C\u002Fp\u003E\u003Cp\u003E
if err := GetEntity(req, &u); err != nil {\u003C\u002Fp\u003E\u003Cp\u003E
\u002F\u002F ...\u003C\u002Fp\u003E\u003Cp\u003E
}\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E这样每次增加一种类型,都只需定义其内容和UnmarshalHTTP函数,然后调用统一的函数GetEntity来获取自己想要的数据。我们只需要将重点放在HTTP handlers的编写上。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003EGO语言和其它语言还有一个不同点,var u User 的时候,GO语言将会自动的初始化所有的变量,比如User是个结构体,那么结构体里的数据都将被初始化,不会造成有的语言不初始化出现乱值的情况。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Ci\u003E**\u003C\u002Fi\u003E*\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E##结束语\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E请记住以下几点:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E1. 设计的时候要根据类型的函数的共同点设计,而不是根据数据的共同点。\u003C\u002Fp\u003E\u003Cp\u003E2. interface{} 不是任意的类型,而是interface{}类型\u003C\u002Fp\u003E\u003Cp\u003E3. 接口由两个words组成;一个指向数据,一个指向方法的表\u003C\u002Fp\u003E\u003Cp\u003E4. 用interface{}最为参数比作为返回值好\u003C\u002Fp\u003E\u003Cp\u003E5. 变量作为接收者的函数,可以用指针调用,但反之不行\u003C\u002Fp\u003E\u003Cp\u003E6. 所有的变量做为参数的时候都以值得形式传递,包括函数的接收者\u003C\u002Fp\u003E\u003Cp\u003E7. 一个interface变量不能严格意义的说是指针或者不是指针类型,它只是interface\u003C\u002Fp\u003E\u003Cp\u003E8. 如果你想在函数内部想完全重写一个值,使用*操作来解除指针的引用.\u003C\u002Fp\u003E\u003Cp\u003E\u003C\u002Fp\u003E&,&updated&:new Date(&T14:11:16.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:0,&collapsedCount&:0,&likeCount&:0,&state&:&published&,&isLiked&:false,&slug&:&&,&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&Go 语言&}],&adminClosedComment&:false,&titleImageSize&:{&width&:0,&height&:0},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&tipjarState&:&closed&,&annotationAction&:[],&sourceUrl&:&&,&pageCommentsCount&:0,&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T22:11:16+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[],&summary&:&#GO语言面向对象编程之接口(下)# Go's interfaces—static, checked at compile time, dynamic when asked for—are, for me, the most exciting part of Go from a language design point of view. If I could export one feature of Go into other lang…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&annotationDetail&:null,&commentsCount&:0,&likesCount&:0,&FULLINFO&:true}},&User&:{&wang-wen-xue-3-2&:{&isFollowed&:false,&name&:&王文学&,&headline&:&&,&avatarUrl&:&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-ca69e8a747cb_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&wang-wen-xue-3-2&,&bio&:&哈哈哈&,&hash&:&a4bee85fe3b268accc8730a&,&uid&:951200,&isOrg&:false,&description&:&&,&badge&:{&identity&:null,&bestAnswerer&:null},&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fwang-wen-xue-3-2&,&avatar&:{&id&:&v2-ca69e8a747cb&,&template&:&https:\u002F\u002Fpic3.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}},&Comment&:{},&favlists&:{}},&me&:{},&global&:{&experimentFeatures&:{&ge3&:&ge3_9&,&ge2&:&ge2_1&,&growthSearch&:&s0&,&nwebQAGrowth&:&experiment&,&qawebRelatedReadingsContentControl&:&open&,&marketTabBanner&:&market_tab_banner_show&,&liveStore&:&ls_a2_b2_c1_f2&,&qawebThumbnailAbtest&:&new&,&nwebSearch&:&nweb_search_heifetz&,&enableVoteDownReasonMenu&:&enable&,&showVideoUploadAttention&:&true&,&isOffice&:&false&,&enableTtsPlay&:&post&,&newQuestionDiversion&:&true&,&wechatShareModal&:&wechat_share_modal_show&,&newLiveFeedMediacard&:&old&,&androidPassThroughPush&:&all&,&hybridZhmoreVideo&:&no&,&nwebGrowthPeople&:&default&,&nwebSearchSuggest&:&default&,&qrcodeLogin&:&qrcode&,&androidDbFollowRecommendHide&:&open&,&isShowUnicomFreeEntry&:&unicom_free_entry_off&,&newMobileColumnAppheader&:&new_header&,&androidDbCommentWithRepinRecord&:&open&,&feedHybridTopicRecomButtonIcon&:&yes&,&androidDbRecommendAction&:&open&,&zcmLighting&:&zcm&,&androidDbFeedHashTagStyle&:&button&,&appStoreRateDialog&:&close&,&topWeightSearch&:&new_top_search&,&default&:&None&,&isNewNotiPanel&:&no&,&androidDbRepinSelection&:&open&,&growthBanner&:&default&,&androidProfilePanel&:&panel_b&}},&columns&:{&next&:{}},&columnPosts&:{},&columnSettings&:{&colomnAuthor&:[],&uploadAvatarDetails&:&&,&contributeRequests&:[],&contributeRequestsTotalCount&:0,&inviteAuthor&:&&},&postComments&:{},&postReviewComments&:{&comments&:[],&newComments&:[],&hasMore&:true},&favlistsByUser&:{},&favlistRelations&:{},&promotions&:{},&switches&:{&couldSetPoster&:false},&draft&:{&titleImage&:&&,&titleImageSize&:{},&isTitleImageFullScreen&:false,&canTitleImageFullScreen&:false,&title&:&&,&titleImageUploading&:false,&error&:&&,&content&:&&,&draftLoading&:false,&globalLoading&:false,&pendingVideo&:{&resource&:null,&error&:null}},&drafts&:{&draftsList&:[],&next&:{}},&config&:{&userNotBindPhoneTipString&:{}},&recommendPosts&:{&articleRecommendations&:[],&columnRecommendations&:[]},&env&:{&edition&:{&baidu&:false,&yidianzixun&:false,&qqnews&:false},&isAppView&:false,&appViewConfig&:{&content_padding_top&:128,&content_padding_bottom&:56,&content_padding_left&:16,&content_padding_right&:16,&title_font_size&:22,&body_font_size&:16,&is_dark_theme&:false,&can_auto_load_image&:true,&app_info&:&OS=iOS&},&isApp&:false,&userAgent&:{&ua&:&Mozilla\u002F5.0 (compatible, MSIE 11, Windows NT 6.3; Trident\u002F7.0; rv:11.0) like Gecko&,&browser&:{&name&:&IE&,&version&:&11&,&major&:&11&},&engine&:{&version&:&7.0&,&name&:&Trident&},&os&:{&name&:&Windows&,&version&:&8.1&},&device&:{},&cpu&:{}}},&message&:{&newCount&:0},&pushNotification&:{&newCount&:0}}

我要回帖

更多关于 汇编语言 的文章

 

随机推荐