Mehrere Rückgabewerte



  • Mehrere Funktionsparameter sind selbstverständlich.
    Mehrere Rückgabewerte aber immer noch wenig verbreitet in Programmiersprachen. Ich glaube nur einige funktionale Sprachen können auf natürliche Weise mit solchen Rückgabetupeln umgehen.

    Warum ist sowas nicht genauso selbstverständlich wie mehrere Parameter?

    //Definition
    (int, string) foo()
    {
    	return (23, "huhu");
    }
    
    //Aufruf
    (int x, string s) = foo();
    

    Stattdessen muss man die Werte in andere Objekte verpacken oder Referenzparameter verwenden.

    Übersehe ich irgendeinen technischen Grund der dagegen spricht?



  • Eigentlich nicht, da man die Rückgabe-Tupel etwas wie anonyme Structs behandeln kann.

    //Definition
    (int, string) foo()
    {
        return (23, "huhu");
    }
    
    //Aufruf
    (int x, string s) = foo();
    

    könnte der Compiler ja einfach in das übersetzen:

    struct int_str_tuple
    {
        int _1;
        string _2;
    };
    
    int_str_tuple foo()
    {
        return { 23, "huhu" };
    }
    
    int_str_tuple result = foo();
    int x = result._1;
    string s = result._2;
    

    Sollte keinen technischen Aufwand darstellen.



  • Technisch spricht da nichts gegen. Einige Programmiersprachen unterstützen auch mehrere Rückgabewerte, zB Go, Python, Common Lisp.

    In C++ muss man es halt ein bisschen mühevoller machen

    #include <tuple>
    #include <string>
    #include <iostream>
    using namespace std;
    
    auto foo() -> tuple<int, std::string> {
      return make_tuple(23, "huhu");
    }
    
    int main() {
      int x;
      string s;
      tie(x, s) = foo();
    
      cout << x << ", " << s << endl;
    }
    


  • Ethon schrieb:

    Eigentlich nicht, da man die Rückgabe-Tupel etwas wie anonyme Structs behandeln kann.

    Eben. Komplexer ist das ganze auch nicht. Der Go-Compiler setzt das auch genau so um.

    Als weitere Sprache, die sowas anbietet, ist noch Lua zu nennen.

    Gerade um Fehler an den Aufrufer zu signalisieren ist das ganze wirklich praktisch. Nicht immer ist das Uberladen des eigentlichen Rückgabewerts möglich, geschweige denn sonderlich elegant.



  • Kotnascher schrieb:

    Gerade um Fehler an den Aufrufer zu signalisieren ist das ganze wirklich praktisch. Nicht immer ist das Uberladen des eigentlichen Rückgabewerts möglich, geschweige denn sonderlich elegant.

    Da bieten sich Exceptions an.



  • Tupel schrieb:

    Übersehe ich irgendeinen technischen Grund der dagegen spricht?

    Technisch nicht, eher logisch: was passiert, wenn der Rückgabewert in einem Ausdruck verwendet wird?

    foo() + foo()
    

    Was wird gemacht und was ist der Wert des Ausdrucks? Sinvoll wäre eigentlich nur Fehler oder stillschweigendes Verwenden des ersten Wertes. Könnte man sicherlich machen, in vielen Sprachen hat man sich jedoch entschieden, das gar nicht erst zuzulassen. Und anonyme Strukturen haben eben in dem Zusammenhang das Problem, dass man noch eine Syntax anbieten müsste, um auf die Komponenten zugreifen zu können. Also einfach tuple benutzen, unter anderem dafür ist es da.


Log in to reply