Rolf B: Class Diagram - Übergabemodus bei Operation verstehen

Beitrag lesen

Hallo MB,

ich bin kein UML Papst, aber +getFoo( out ) :float kann eigentlich keinen Sinn ergeben. in/out/inout geben an, welchen Weg die Daten bei diesem Parameter nehmen.

in: Der Aufrufer übergibt der Funktion einen float Wert. out: Die Funktion hinterlegt hier für die Funktion einen Wert inout: Der Aufrufer übergibt einen Wert und die Funktion kann ihn ändern.

Die Angabe hinter der schließenden Klammer gibt an, welchen Typ der Rückgabewert der Funktion hat.

in

UML: doSomething(in foo: float) : int
PHP: function doSomething($foo: float) : int { return 4711; }

Beachte: PHP kennt mittlerweile ebenfalls Typdeklarationen für die Rückgabe.

out

UML: doSomething(out foo: float) : int

Diese Funktion gibt zwei Werte zurück. Einen int-Wert als normalen return-Wert, und einen float-Wert im out-Parameter foo. Dafür muss sie diesem Parameter einen Wert zuweisen. Einen Wert in die Funktion hineingeben kannst Du mit dieser Aufrufkonvention nicht. In Sprachen wie C# gibt's sogar einen Compile-Fehler, wenn eine Funktion einem out-Parameter nichts zuweist.

PHP: Es gibt kein reinen out-Parameter. Nur inout. Auch „Referenzen“ genannt.

inout

UML: doSomething(inout foo: float) : int

Diese Funktion gibt ebenfalls zwei Werte zurück. Einen int-Wert als normalen return-Wert, und einen float-Wert im out-Parameter foo. Der Unterschied zur vorigen Signatur ist, dass die Funktion in foo auch noch einen Wert entgegennimmt. In PHP löst man das mit einem Referenzparameter, erkennbar am & vor dem $ in der Funktionsdeklaration. Aber nur dort, nicht beim Aufruf. Eine typische PHP Methode, sich in den Fuß zu schießen! Das ist in anderen Sprache anders, da muss man den call-by-reference auf beiden Seiten festlegen. Damit man beim Aufruf und in der Funktion sieht, dass das passiert.

Angesichts dieser Syntaxschwäche sollte man inout nach Möglichkeit meiden und nur Rückgabewerte nutzen. Man kann zur Not ein Array mit mehreren Werten darin zurückgeben.

Syntaxbeispiel in PHP:

function doSomething(&$foo) : int {
   $foo *= 42;
   return intvaö($foo / 1000);
}

$a = 4711;
$milliA = doSomething($a);
// $a ist jetzt 197862, und $milliA ist 197

Aber ich würde das nicht tun. Wenn man zwei Werte zurückgeben will, dann tut man das auch. Dafür gibt's Arrays und den list-Operator. Es mag einen Tick langsamer sein. Aber dafür massiv lesbarer.

function doSomething($foo) : array {
   $bar = $foo * 42;
   return ARRAY($bar, $bar / 1000);
}

$a = 4711;
list($a, $milliA) = doSomething($a);

Du kannst, wenn Du Bedarf an einem out-Parameter zu haben glaubst, ihn in PHP mit einem Referenzparameter implementieren. An dieser Stelle ist es tatsächlich interessant, kein Array zurückzugeben. Nimm an, du hättest eine Funktion, die einen String in eine Zahl konvertiert, aber nur, wenn es auch wirklich eine ist. Hier braucht man zwei Ergebnisse: die geparste Zahl, und ein Flag, ob das Parsing möglich war. In C# heißt diese Funktion tryParseInt. Wenn das Ergebnis ein out-Parameter ist und das Erfolgs-Flag ein bool-return, kann man das so verwenden:

if (tryParseInt($string, $result)) {
   // tu was mit $result
}

und das ist praktischer, als ein Array zurückzugeben. Wenn die Syntax denn klarer wäre. In C# schreibe ich:

if (int.tryParse(stringValue, out result)) {
   // tu was mit $result
}

und da sieht man direkt, dass ein Wert zurückkommt.

Rolf

--
sumpsi - posui - obstruxi