Is Go Duck-Typed?

栏目: IT技术 · 发布时间: 4年前

内容简介:Suppose you see a bird walking around in a farm yard. This bird has no label that says 'duck'. But the bird certainly looks like a duck. Also, he goes to the pond and you notice that he swims like a duck. Then he opens his beak and quacks like a duck. Well

Suppose you see a bird walking around in a farm yard. This bird has no label that says 'duck'. But the bird certainly looks like a duck. Also, he goes to the pond and you notice that he swims like a duck. Then he opens his beak and quacks like a duck. Well, by this time you have probably reached the conclusion that the bird is a duck, whether he's wearing a label or not.

The previous quote was not the first invocation of the duck test but it is the most famous. The usage of this test may date back to the early 20th century as a way of arguing that “given the properties I can observe about some object, I’m going to classify it as what it appears to be.” It is sometimes deployed as a counterargument to claims that something is not what it seems.

The question before the house today is this: Is go duck-typed? Other languages claim to be so (see below), and the go team has mentioned in public presentations an affinity for this particular type strategy.

Duck Typing

In programming languages, duck typing can be roughly approximated as the application of the duck test to objects. To increase the precision slightly, a type is defined to be a collection of things that the type can do. Let’s try a go-ish example:

Thus, we will define some type to be an Animal if it can return the number of legs it has. The previous is an example of an interface in go, so it implies that there are one or more implementations. An interface in go is a “test” in the sense of the duck test above; this type declaration is an animal test .

Given the animal test, let’s define a whole zoo!

Given the current Animal interface definition, these are all duck-typed as Animal :

Spider
Dog
Stool

Surely, one cannot have intended a three-legged stool to be an animal?!? Well, if one applies the—admittedly weak—animal test that we constructed with the interface Animal above, the stool certainly passes. The critical idea of duck typing is “can I use the object in question in the way I want” and if so, the object passes the test. Clearly we can improve our definition of the animal test in this way:

With this better version of Animal we can (correctly?) disallow a stool to be considered an animal because it has no Genus() method. This example may seem contrived but by perusing the go standard library one will notice that a great many of the go standard interfaces have one or two methods. In fact,with a small program, one can compute the histogram of the number of methods that occur in interface declarations in the go standard library.

Is Go Duck-Typed?

The histogram above indicates that number of interfaces with one or two methods is greater than three times all the others combined!

Duck Typing and Comparative Programming Languages

The notion of a “type” in a programming language goes back to the origin of programming languages. The arguing about what is a “type” in programming languages goes back to five minutes after the origin of programming languages. Many Ph.D. theses have been written about these arguments, entire conferences are dedicated to the subject, and books are written in an attempt to formally define a type (for example, A Theory of Objects or the Z notation ).  

For the purpose of simplicity we will define an interface to be a type that specifies a contract about how an instance of the type will perform his duties. One could say that the first widely known programming language with the “object must meet the contract” paradigm was Eiffel in 1985, although this is arguable. Given our (simplistic) definition of an interface/contract how do programming languages differ? We’ll divide languages into two categories: those that require the specification of the interface and those that do not.

The most common reason for requiring that an interface be defined is performance, although there are others. The general reason that specifying interfaces provide additional performance is that a traditional compiler or a Just-In-Time (JIT) compiler can make assumptions about the underlying memory layout so long as the specification of the interface is enforced by the language. To use our improved example above with Animal , a hypothetical compiler could assume that the method NumberOfLegs is 0 bytes from the memory address of the instance implementing Animal and the method Genus is located 8 bytes from the memory address of the instance. So long as said  compiler also enforces this requirement when compiling the implementation of Spider and Dog , the code that accepts an Animal can 1) not need to know the true type of the instance passed as a parameter and 2) jump (branch) directly to the memory address of the implementation of NumberOfLegs or Genus for fast performance. Today, many compiled, object-oriented languages from Java (1991) to C# (2000) and from Rust (2010) to Swift (2014) operate with these explicit interfaces (this list is far from exhaustive!).

The other alternative is, well, to just wait. This is the case that is usually considered to be duck typing. In this formulation, you simply pass any type as a parameter to any function or method and wait to see if the parameter is used in a way that is acceptable. So, if type Spider is passed to method Anatomy(a) as the parameter a , there is no check to see if Spider will work in all code paths inside Anatomy . We simply try to run the program and see if the method calls on a ( neé Spider ) work out. If they don’t, we generate an error and abort Anatomy . You can easily imagine a dumb definition of Anatomy() which only calls NumberOfLegs() and since that is allowed on Spider , the Spider as a parameter is ok. Notably, the use of Stool as parameter a would be ok too! In this model, the “contract”–if one can be said to exist–is implicit and varies with the exact code path that is taken through the function Anatomy . Languages like Python (1990) and Ruby (1995) operate in this fashion; the Python community popularized the phrase “duck typing” for this behavior.

Duck Typing and Go

Go is an unusual hybrid of these two ideas. Let’s think about an example: Joe has defined and has exported this package somedwarf :

Joe compiles this code and makes it available to his team.  A week later, Mary writes this code:

If Mary runs her code from main() she’ll see “dwarf is sad” and then on the next line “dwarf is happy.”

Given our poor man’s definition of duck typing earlier, when the language waits to see how the type is used, which case are we in here?

Does go have duck typing or not?

One can make the case that in the small we are in the first case explained above: the interface has to be explicitly defined. Within the code written by Mary, it seems fairly clear that the interface IsHappy is defined so that it can be used to type check the uses of the parameter h in PrintHappy . As we explained previously, IsHappy is being used to accelerate the call to h.Happy() inside PrintHappy .

In the largethough, one can easily argue that we are in the duck typing case above. Joe’s code didn’t know or care about Mary’s code, and since g in Mary’s code worked because it had the proper method for Happy() that is used in (Mary’s) PrintHappy() that effectively we just waited to see if Grumpy could legitimately be used successfully in PrintHappy .

What do we conclude from this? Sometimes, you have to embrace the ambiguity!

Happy go-ing!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

小程序大能量

小程序大能量

肖月 / 人民邮电出版社 / 2018-11 / 49.80元

本书主要针对零基础的读者,详细讲解小程序的搭建以及小程序的运营等知识。全书共有6章。第 1章重点介绍了小程序诞生的原因以及小程序的发展历史;第 2章详细讲解了快速搭建小程序的方法;第3章向读者阐述了小程序和互联网运营的关系;第4章主要介绍了小程序运营的意义;第5章全面分析了打造爆款小程序的策略;第6章重点总结了小程序的营销推广策略。 本书可以作为对小程序感兴趣的个人以及企业的学习用书,帮助读者快速......一起来看看 《小程序大能量》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具