268 Stimmen

Funktionsüberladung nach Rückgabetyp?

Warum unterstützen nicht mehr gängige statisch typisierte Sprachen das Überladen von Funktionen/Methoden nach Rückgabetyp? Ich kann mich an keine erinnern, die das tut. Es scheint nicht weniger nützlich oder sinnvoll zu sein als die Unterstützung von Überladung nach Parametertyp. Wie kommt es, dass es so viel weniger populär ist?

2 Stimmen

0 Stimmen

@user195488 dies ist kein Duplikat, weil es eine allgemeine Frage ist.

1voto

ZORRO_BLANCO Punkte 779

Wenn Sie Methoden mit verschiedenen Rückgabetypen überladen wollen, fügen Sie einfach ein Dummy-Parameter mit Standardwert um die Ausführung der Überladung zu ermöglichen, aber vergessen Sie nicht, dass der Parametertyp unterschiedlich sein sollte, damit die Überladungslogik funktioniert, dann ist ein z.B. auf Delphi:

type    
    myclass = class
    public
      function Funct1(dummy: string = EmptyStr): String; overload;
      function Funct1(dummy: Integer = -1): Integer; overload;
    end;

Verwenden Sie es so

procedure tester;
var yourobject : myclass;
  iValue: integer;
  sValue: string;
begin
  yourobject:= myclass.create;
  iValue:= yourobject.Funct1(); //this will call the func with integer result
  sValue:= yourobject.Funct1(); //this will call the func with string result
end;

0 Stimmen

Das ist eine schreckliche Idee. Führen Sie keine Dummy-Parameter ein, das ist ein großer Code-Geruch. Wählen Sie stattdessen andere Namen, oder wählen Sie einen Rückgabetyp, der sich wie eine diskriminierte Vereinigung oder etwas Ähnliches verhalten kann.

0 Stimmen

@Abel, was Sie vorschlagen, ist eigentlich die schreckliche Idee, denn die ganze Idee ist über diese Dummy-Parameter, und es ist so benannt, um es klar für den Entwickler, dass dieser Parameter ist Dummy und sollte ignoriert werden, auch für den Fall, dass Sie nicht wissen, die Dummy-Parameter mit Standardwerten werden in vielen Bibliotheken, VCL in Delphi, und viele IDEs, z.B. in Delphi können Sie es in der sysutils Einheit in SafeLoadLibrary sehen...

0 Stimmen

Es gibt sicherlich Szenarien, in denen Dummy-Parameter nützlich sind, wie in Lambdas in Map- oder Fold-Operationen oder bei der Implementierung einer Schnittstelle. Aber wenn es nur darum geht, eine Überladung zu erzeugen, kann ich dem nicht zustimmen. Es besteht keine Notwendigkeit, und es ist ein Geräusch, auf das Programmierer verzichten können.

0voto

Codeless Punkte 9

Wie bereits gezeigt, führen zweideutige Aufrufe einer Funktion, die sich nur durch den Rückgabetyp unterscheidet, zu Mehrdeutigkeit. Mehrdeutigkeit führt zu fehlerhaftem Code. Defekter Code muss vermieden werden.

Die Komplexität, die durch den Versuch der Zweideutigkeit entsteht, zeigt, dass dies kein guter Hack ist. Abgesehen von einer intellektuellen Übung - warum nicht Verfahren mit Referenzparametern verwenden.

procedure(reference string){};
procedure(reference int){};
string blah;
procedure(blah)

0 Stimmen

Denn Sie können die "Rückgabewerte" nicht einfach sofort wiederverwenden. Sie müssten jeden Aufruf in einer einzigen Zeile ausführen, im Gegensatz zu doing(thisVery(deeplyNested(), andOften(butNotAlways()), notReally()), goodCode());

0voto

paulon0n Punkte 1

Diese überlastungsfunktion ist nicht schwer zu handhaben, wenn man sie etwas anders betrachtet. betrachten sie folgendes,

public Integer | String f(int choice){
if(choice==1){
return new string();
}else{
return new Integer();
}}

Wenn eine Sprache das Überladen zurückgibt, würde sie das Überladen von Parametern erlauben, nicht aber Duplikationen. Dies würde das Problem der:

main (){
f(x)
}

weil es nur ein f(int choice) gibt, aus dem man wählen kann.

0voto

Facundo Punkte 1

In .NET verwenden wir manchmal einen Parameter, um die gewünschte Ausgabe eines generischen Ergebnisses anzugeben, und nehmen dann eine Konvertierung vor, um das zu erhalten, was wir erwarten.

C

public enum FooReturnType{
        IntType,
        StringType,
        WeaType
    }

    class Wea { 
        public override string ToString()
        {
            return "Wea class";
        }
    }

    public static object Foo(FooReturnType type){
        object result = null;
        if (type == FooReturnType.IntType) 
        {
            /*Int related actions*/
            result = 1;
        }
        else if (type == FooReturnType.StringType)
        {
            /*String related actions*/
            result = "Some important text";
        }
        else if (type == FooReturnType.WeaType)
        {
            /*Wea related actions*/
            result = new Wea();
        }
        return result;
    }

    static void Main(string[] args)
    {
        Console.WriteLine("Expecting Int from Foo: " + Foo(FooReturnType.IntType));
        Console.WriteLine("Expecting String from Foo: " + Foo(FooReturnType.StringType));
        Console.WriteLine("Expecting Wea from Foo: " + Foo(FooReturnType.WeaType));
        Console.Read();
    }

Vielleicht kann auch dieses Beispiel helfen:

C++

    #include <iostream>

enum class FooReturnType{ //Only C++11
    IntType,
    StringType,
    WeaType
}_FooReturnType;

class Wea{
public:
    const char* ToString(){
        return "Wea class";
    }
};

void* Foo(FooReturnType type){
    void* result = 0;
    if (type == FooReturnType::IntType) //Only C++11
    {
        /*Int related actions*/
        result = (void*)1;
    }
    else if (type == FooReturnType::StringType) //Only C++11
    {
        /*String related actions*/
        result = (void*)"Some important text";
    }
    else if (type == FooReturnType::WeaType) //Only C++11
    {
        /*Wea related actions*/
        result = (void*)new Wea();
    }
    return result;
}

int main(int argc, char* argv[])
{
    int intReturn = (int)Foo(FooReturnType::IntType);
    const char* stringReturn = (const char*)Foo(FooReturnType::StringType);
    Wea *someWea = static_cast<Wea*>(Foo(FooReturnType::WeaType));
    std::cout << "Expecting Int from Foo: " << intReturn << std::endl;
    std::cout << "Expecting String from Foo: " << stringReturn << std::endl;
    std::cout << "Expecting Wea from Foo: " << someWea->ToString() << std::endl;
    delete someWea; // Don't leak oil!
    return 0;
}

1 Stimmen

Es ist etwas hakelig und könnte zu Laufzeitfehlern führen, wenn der Benutzer das Ergebnis nicht richtig umwandelt oder wenn der Entwickler die Rückgabetypen nicht richtig mit der Enum abgleicht. Ich würde empfehlen, einen vorlagenbasierten Ansatz (oder generische Parameter in C#?) zu verwenden, wie in diese Antwort

0voto

YvesgereY Punkte 3538

Für das Protokoll, Oktave ermöglicht unterschiedliche Ergebnisse, je nachdem, ob das Rückgabeelement ein Skalar oder ein Array ist.

x = min ([1, 3, 0, 2, 0])
     x = 0

[x, ix] = min ([1, 3, 0, 2, 0])
     x = 0
      ix = 3 (item index)

Siehe auch Singulärwert-Zerlegung .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X