Jak zwrócić wiele wartości z funkcji Delphi?

O parametrach procedury/funkcji i typach zwrotów: Var, Out, Record

Najpopularniejsza konstrukcja w Delfy aplikacja byłaby procedura lub funkcja . Znane jako procedury, procedury lub funkcje to bloki instrukcji, które wywołujesz z różnych miejsc w programie.





Mówiąc prościej, procedura to procedura, która nie zwraca wartości, podczas gdy funkcja zwraca wartość.

Wartość zwracana z funkcji jest zdefiniowana przez typ zwracany. W większości przypadków napisałbyś funkcję do zwrócić pojedynczą wartość będzie to liczba całkowita, łańcuch, boolean lub inny prosty typ, również typy zwracane mogą być tablicą, listą ciągów, instancją niestandardowego obiektu lub podobnym.



Zauważ, że nawet jeśli twoja funkcja zwraca listę ciągów (zbiór smyczki ) nadal zwraca pojedynczą wartość: jedno wystąpienie listy ciągów.

Co więcej, procedury Delphi mogą mieć naprawdę wiele twarzy: rutyna, metoda, wskaźnik metody, delegowanie zdarzeń, metoda anonimowa...



Czy funkcja może zwrócić wiele wartości?

Pierwsza odpowiedź, jaka przychodzi mi do głowy, brzmi nie, po prostu dlatego, że kiedy myślimy o funkcji, myślimy o pojedynczej wartości zwracanej.

Z pewnością jednak odpowiedź na powyższe pytanie brzmi: tak. Funkcja może zwrócić kilka wartości. Zobaczmy jak.

Parametry Var

Ile wartości może zwrócić następująca funkcja, jedna lub dwie?

|_+_||_+_|

Funkcja oczywiście zwraca wartość logiczną (prawda lub fałsz). Co powiesz na drugi parametr „valueOut” zadeklarowany jako parametr „VAR” (zmienna)?



Parametry Var są przekazywane do funkcji przez odniesienie co oznacza, że ​​jeśli funkcja zmieni wartość parametru — zmienną w wywołującym bloku kodu — funkcja zmieni wartość zmiennej użytej jako parametr.

Aby zobaczyć, jak powyższe działa, oto implementacja:



|_+_||_+_|
|_+_|
|_+_|
|_+_|
|_+_|

Wartość 'valueIn' jest przekazywana jako stały parametr — funkcja nie może go zmienić i jest traktowana jako tylko do odczytu.

Jeśli 'valueIn' lub jest większe od zera, parametrowi 'valueOut' przypisywana jest wartość odwrotna 'valueIn', a wynik funkcji jest prawdziwy. Jeśli wartość In wynosi<= 0 then the function returns false and 'valueOut' is not altered in any way.



Oto użycie:

|_+_||_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|

Dlatego PositiveReciprocal faktycznie może 'zwrócić' 2 wartości! Używając parametrów var, możesz sprawić, by procedura zwracała więcej niż jedną wartość.



Parametry wyjściowe

Istnieje inny sposób określenia parametru przez odwołanie — za pomocą słowa kluczowego „out”, jak w:

|_+_||_+_|
|_+_|
|_+_|
|_+_|
|_+_|

Implementacja PositiveReciprocalOut jest taka sama jak w PositiveReciprocal, jest tylko jedna różnica: 'valueOut' jest parametrem OUT.

W przypadku parametrów zadeklarowanych jako „out” wartość początkowa zmiennej „valueOut” przywoływanej jest odrzucana.

Oto użycie i wyniki:

|_+_||_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|
|_+_|

Zauważ, że w drugim wywołaniu wartość zmiennej lokalnej 'r' jest ustawiona na '0'. Wartość 'r' została ustawiona na 5 przed wywołaniem funkcji, ale ponieważ parametr został zadeklarowany jako 'out', gdy 'r' osiągnął funkcję, wartość została odrzucona i dla parametru została ustawiona domyślna wartość 'pusta' (0 dla prawdziwego typu).

W rezultacie możesz bezpiecznie wysyłać niezainicjowane zmienne dla parametrów out — coś, czego nie powinieneś robić z parametrami „var”. Parametry są używane do wysyłania czegoś do procedury, z wyjątkiem tego z parametrami 'out' :), a zatem niezainicjowane zmienne (używane do parametrów VAR) mogą mieć dziwne wartości.

Zwracanie rekordów?

Powyższe implementacje, w których funkcja zwracałaby więcej niż jedną wartość, nie są miłe. Funkcja faktycznie zwraca pojedynczą wartość, ale zwraca również, lepiej powiedzieć alters, wartości parametrów var/out.

Z tego powodu bardzo rzadko możesz chcieć używać parametrów przez odwołanie. Jeśli wymaganych jest więcej wyników z funkcji, możesz zwrócić funkcję aRozważ następujące:

|_+_||_+_|
|_+_|
|_+_|
|_+_|
|_+_|

oraz funkcję hipotetyczną:

|_+_||_+_|

Funkcja WhereAmI zwróciłaby Szerokość i długość geograficznadla danego miasta (miasto, obszar, ...).

Wdrożenie byłoby:

|_+_||_+_|
|_+_|
|_+_|
|_+_|
|_+_|

A tutaj mamy funkcję zwracającą 2 wartości rzeczywiste. Ok, zwraca 1 rekord, ale ten rekord ma 2 pola. Zauważ, że możesz mieć bardzo złożony rekord mieszający różne typy, które mają być zwrócone w wyniku działania funkcji.

Otóż ​​to. Dlatego tak, funkcje Delphi mogą zwracać wiele wartości.