anyway, you're right, it's not duck typing. Duck typing happens at runtime. With Go, every variable has exactly one type at compile time. Sometimes that type is an interface type. With duck typing, the checking happens at runtime. There's no runtime type checking with Go's interface system.
Except when there is: http://golang.org/ref/spec#Type_assertions
The only requirement to duck typing is "an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface".
This is exactly how Go's interfaces work. You define the methods you require an argument to have, and then anything that has those methods can be used as that argument, without the original type having any knowledge of the interface that was designed. The only difference between Go and Python in this regard is that Python doesn't actually define what a duck is for a specific method, it is implicitly defined by the methods that are called on it. Go explicitly defines what a duck is, which makes it a hell of a lot easier to know if the object you're passing in qualifies as a duck without reading every line in the damn function.
Yes, go checks that an object is a duck at compile time, that doesn't have anything to do with duck typing.
Structural typing looks for structural isomorphsims - it is total. Duck typing looks at run time compatibility, so long as the runtime accessed portion is the correct signature it passes.
So structural typing is about isomorphisms and duck typing is about checking the correct boxes before entry. Both have the attribute of looking at structure but you cannot expect them to cluster types in the same manner.
In ML* terms I like to think of structural typing making hard clusters and Duck typing allowing for soft clusters.
* No, not that ML.
But you cannot expect them to always behave the same way. That is, { f_d(t) | t ∈ T} <> {f_s(t) : t ∈ T} where f : T -> T set takes a type and returns the set of types in T equal to it and f_s , f_d check for equivalence via structural and ducks respectively. You can expect f_s to also define a partition over T but not necessarily the same for f_d. f_d is vaguely defined there but if you pretend it acts like it simulates how a runtime check would occur, |f_d| will tend to be >= than |f_s|
An example of how structural typing is not just compile time duck typing is because such a thing exists (in F#) and is not the same as structural typing.
let's put it in another perspective: if you have a function that takes disparate types, then the thing that's passed in that function may be of arbitrary type. It's unknown at compile time how much memory will be allocated for the instantiation of that function in order to accept the parameter, because the type that's being passed it is unknown. In structural typing, like in Go, you know at compile time the type of the thing being passed in, and therefore, the amount of resources that will be required upon calling.
Or in another sense, an array of an interface value in Go has a well-defined memory layout, whereas an array of disparate types in a dynamic language does not have a well-defined memory layout at compile time.
internally, an interface value in Go is a two-tuple; it's an actual additional structure; it boxes the structure we're interested in. With duck typing, there is no box.
so yes, it's actually very different. The difference is more meaningful than people generally let on.
Of course inferred structural types should also have that feature, if all structural types are left inferred.
Translated to Go: "When I see a type with methods that satisfy this interface, then it implements this interface."
Basically, the interface just defines at compile time what Python defines at runtime... except it's a hell of a lot easier to see what methods are required for a Go interface, than it is to see what methods are required for a python function (you basically have to read the entire function and any function that function passes the argument to).
Not that I don't like python, I do.
I don't really think that is true in Go.