How is duck typing different from the old 'variant' type and/or interfaces?

后端 未结 10 997
无人及你
无人及你 2021-01-30 03:32

I keep seeing the phrase \"duck typing\" bandied about, and even ran across a code example or two. I am way too lazy busy to do my own research, can someone tel

相关标签:
10条回答
  • 2021-01-30 03:50

    Duck typing is just another term for dynamic typing or late-binding. A variant object that parses/compiles with any member access (e.g., obj.Anything) that may or not actually be defined during runtime is duck typing.

    0 讨论(0)
  • 2021-01-30 03:51

    Probably nothing requires duck-typing, but it can be convenient in certain situations. Say you have a method that takes and uses an object of the sealed class Duck from some 3rd party library. And you want to make the method testable. And Duck has an awfully big API (kind of like ServletRequest) of which you only need to care about a small subset. How do you test it?

    One way is to make the method take something that quacks. Then you can simply create a quacking mock object.

    0 讨论(0)
  • 2021-01-30 03:55

    In some of the answers here, I've seen some incorrect use of terminology, which has lead people to provide wrong answers.

    So, before I give my answer, I'm going to provide a few definitions:

    1. Strongly typed

      A language is strongly typed if it enforces the type safety of a program. That means that it guarantees two things: something called progress and something else called preservation. Progress basically means that all "validly typed" programs can in fact be run by the computer, They may crash, or throw an exception, or run for an infinite loop, but they can actually be run. Preservation means that if a program is "validly typed" that it will always be "Validly typed", and that no variable (or memory location) will contain a value that does not conform to its assigned type.

      Most languages have the "progress" property. There are many, however, that don't satisfy the "preservation" property. A good example, is C++ (and C too). For example, it is possible in C++ to coerce any memory address to behave as if it was any type. This basically allows programmers to violate the type system any time they want. Here is a simple example:

      struct foo
      {
          int x;
          iny y;
          int z;
      }
      
      char * x = new char[100];
      foo * pFoo = (foo *)x;
      foo aRealFoo;
      *pFoo = aRealFoo;
      

      This code allows someone to take an array of characters and write a "foo" instance to it. If C++ was strongly typed this would not be possible. Type safe languages, like C#, Java, VB, lisp, ruby, python, and many others, would throw an exception if you tried to cast an array of characters to a "foo" instance.

    2. Weakly typed

      Something is weakly typed if it is not strongly typed.

    3. Statically typed

      A language is statically typed if its type system is verified at compile time. A statically typed language can be either "weakly typed" like C or strongly typed like C#.

    4. Dynamically typed

      A dynamically typed language is a language where types are verified at runtime. Many languages have a mixture, of some sort, between static and dynamic typing. C#, for example, will verify many casts dynamically at runtime because it's not possible to check them at compile time. Other examples are languages like Java, VB, and Objective-C.

      There are also some languages that are "completely" or "mostly" dynamically typed, like "lisp", "ruby", and "small talk"

    5. Duck typing

      Duck typing is something that is completely orthogonal to static, dynamic, weak, or strong typing. It is the practice of writing code that will work with an object regardless of its underlying type identity. For example, the following VB.NET code:

      function Foo(x as object) as object
          return x.Quack()
      end function
      

      Will work, regardless of what the type of the object is that is passed into "Foo", provided that is defines a method called "Quack". That is, if the object looks like a duck, walks like a duck, and talks like a duck, then it's a duck. Duck typing comes in many forms. It's possible to have static duck typing, dynamic duck typing, strong duck typing, and weak duck typing. C++ template functions are a good example of "weak static duck typing". The example show in "JaredPar's" post shows an example of "strong static duck typing". Late binding in VB (or code in Ruby or Python) enables "strong dynamic duck typing".

    6. Variant

      A variant is a dynamically typed data structure that can hold a range of predefined data types, including strings, integer types, dates, and com objects. It then defines a bunch of operations for assigning, converting, and manipulating data stored in variants. Whether or not a variant is strongly typed depends on the language in which it is used. For example, a variant in a VB 6 program is strongly typed. The VB runtime ensures that operations written in VB code will conform to the typing rules for variants. Tying to add a string to an IUnknown via the variant type in VB will result in a runtime error. In C++, however, variants are weakly typed because all C++ types are weakly typed.

    OK.... now that I have gotten the definitions out of the way, I can now answer your question:

    A variant, in VB 6, enables one form of doing duck typing. There are better ways of doing duck typing (Jared Par's example is one of the best), than variants, but you can do duck typing with variants. That is, you can write one piece of code that will operate on an object regardless of its underlying type identity.

    However, doing it with variants doesn't really give a lot of validation. A statically typed duck type mechanism, like the one JaredPar describes gives the benefits of duck typing, plus some extra validation from the compiler. That can be really helpful.

    0 讨论(0)
  • 2021-01-30 03:58

    I think the core point of duck typing is how it is used. One uses method detection and introspection of the entity in order to know what to do with it, instead of declaring in advance what it will be ( where you know what to do with it ).

    It's probably more practical in OO languages, where primitives are not primitives, and are instead objects.

    I think the best way to sum it up, in variant type, an entity is/can be anything, and what it is is uncertain, as opposed to an entity only looks like anything, but you can work out what it is by asking it.

    Here's something I don't believe is plausible without ducktyping.

    sub dance { 
         my $creature = shift;
         if( $creature->can("walk") ){ 
             $creature->walk("left",1);
             $creature->walk("right",1); 
             $creature->walk("forward",1);
             $creature->walk("back",1);
         }
         if( $creature->can("fly") ){ 
              $creature->fly("up"); 
              $creature->fly("right",1); 
              $creature->fly("forward",1); 
              $creature->fly("left", 1 ); 
              $creature->fly("back", 1 ); 
              $creature->fly("down");
         } else if ( $creature->can("walk") ) { 
             $creature->walk("left",1);
             $creature->walk("right",1); 
             $creature->walk("forward",1);
             $creature->walk("back",1);
         } else if ( $creature->can("splash") ) { 
             $creature->splash( "up" ) for ( 0 .. 4 ); 
         }
         if( $creature->can("quack") ) { 
             $creature->quack();
         }
     }
    
     my @x = ();  
     push @x, new Rhinoceros ; 
     push @x, new Flamingo; 
     push @x, new Hyena; 
     push @x, new Dolphin; 
     push @x, new Duck;
    
     for my $creature (@x){
    
        new Thread(sub{ 
           dance( $creature ); 
        }); 
     }
    

    Any other way would require you to put type restrictions on for functions, which would cut out different species, needing you to create different functions for different species, making the code really hellish to maintain.

    And that really sucks in terms of just trying to perform good choreography.

    0 讨论(0)
提交回复
热议问题