Pierwsza funkcja w pliku m (tj. Funkcja główna ) jest wywoływana po wywołaniu tego pliku m. Nie jest wymagane, aby funkcja główna miała taką samą nazwę jak plik m, ale dla jasności powinna . Gdy funkcja i nazwa pliku różnią się, nazwa pliku musi być użyta do wywołania funkcji głównej.
Wszystkie kolejne funkcje w pliku m, zwane funkcjami lokalnymi (lub „podfunkcjami” w starszej terminologii), mogą być wywoływane tylko przez funkcję główną i inne funkcje lokalne w tym pliku m. Funkcje innych plików m nie mogą ich wywoływać. Począwszy od wersji R2016b, można również dodawać funkcje lokalne do skryptów , chociaż zachowanie zakresu jest nadal takie samo (tzn. Można je wywoływać tylko ze skryptu).
Ponadto możesz zadeklarować funkcje w ramach innych funkcji. Są to tak zwane funkcje zagnieżdżone i można je wywoływać tylko z funkcji, w której są zagnieżdżone. Mogą również mieć dostęp do zmiennych w funkcjach, w których są zagnieżdżone, co czyni je dość przydatnymi, choć nieco trudnymi w pracy.
Więcej jedzenia do przemyślenia ...
Istnieje kilka sposobów opisanych powyżej normalnego zachowania zakresu funkcji, takich jak przekazywanie uchwytów funkcji jako argumentów wyjściowych, jak wspomniano w odpowiedziach SCFrench i Jonasa (które, począwszy od R2013b, jest ułatwione przez localfunctions
funkcję). Nie sugeruję jednak, aby nawyk polegał na stosowaniu takich sztuczek, ponieważ prawdopodobnie istnieją znacznie lepsze opcje organizowania funkcji i plików.
Na przykład, powiedzmy, że masz główną funkcję A
w m-pliku A.m
, wraz z lokalnych funkcji D
, E
oraz F
. Teraz załóżmy, że masz dwie inne powiązane funkcje B
i C
w M-Files B.m
i C.m
, odpowiednio, że chcemy także, aby móc zadzwonić D
, E
i F
. Oto kilka opcji, które masz:
Umieść D
, E
i F
każdy w osobnych plikach m, umożliwiając wywoływanie ich przez dowolną inną funkcję. Minusem jest to, że zakres tych funkcji jest duża i nie ogranicza się tylko A
, B
i C
, ale Plusem jest to, że jest to całkiem proste.
Utwórz plik defineMyFunctions
m (jak w przykładzie Jonasa) za pomocą D
, E
oraz F
jako funkcje lokalne i główna funkcja, która po prostu zwraca do nich uchwyty funkcji. Pozwala to zachować D
, E
i F
w tym samym pliku, ale nie robi nic w odniesieniu do zakresu tych funkcji, ponieważ każda funkcja, która może zostać wywołana, defineMyFunctions
może je wywołać. Musisz także obawiać się o przekazanie uchwytów funkcji jako argumentów, aby upewnić się, że masz je tam, gdzie ich potrzebujesz.
Skopiować D
, E
a F
do B.m
i C.m
jako funkcje lokalnych. To ogranicza zakres ich wykorzystania do właśnie A
, B
i C
, ale czyni aktualizację i utrzymanie kodu koszmar bo masz trzy kopie tego samego kodu w różnych miejscach.
Korzystaj z funkcji prywatnych ! Jeśli masz A
, B
oraz C
w tym samym katalogu, można utworzyć podkatalog o nazwie private
i miejsce D
, E
i F
tam, każdy jako oddzielny m-pliku. To ogranicza ich zakres, więc mogą być wywoływane tylko przez funkcje w katalogu natychmiast powyżej (tj A
, B
i C
) i utrzymuje je razem w tym samym miejscu (ale wciąż różne M-Files):
myDirectory/
A.m
B.m
C.m
private/
D.m
E.m
F.m
Wszystko to nieco wykracza poza zakres twojego pytania i jest prawdopodobnie bardziej szczegółowe niż potrzebujesz, ale pomyślałem, że dobrze byłoby poruszyć bardziej ogólną troskę o uporządkowanie wszystkich twoich m-plików. ;)
^
: @idigasZasadniczo odpowiedź na twoje pytanie brzmi: nie, nie możesz zdefiniować więcej niż jednej widocznej z zewnątrz funkcji na plik. Można jednak zwrócić uchwyty funkcji do funkcji lokalnych, a wygodnym sposobem na to jest utworzenie z nich pól struktury. Oto przykład:
A oto jak można go użyć:
źródło
Jedynym sposobem na posiadanie wielu osobno dostępnych funkcji w jednym pliku jest zdefiniowanie METOD STATYCZNYCH przy użyciu programowania obiektowego . Chcesz uzyskać dostęp do funkcji jako
myClass.static1()
,myClass.static2()
etc.Funkcjonalność OOP jest oficjalnie obsługiwana od wersji R2008a, więc jeśli nie chcesz używać starej, nieudokumentowanej składni OOP, odpowiedź dla Ciebie jest przecząca , jak wyjaśnia @gnovice .
EDYTOWAĆ
Jeszcze jednym sposobem zdefiniowania wielu funkcji w pliku, które są dostępne z zewnątrz, jest utworzenie funkcji, która zwraca wiele uchwytów funkcji . Innymi słowy, wywołalibyśmy funkcję definiującą jako
[fun1,fun2,fun3]=defineMyFunctions
, po czym można użyćout1=fun1(inputs)
itd.źródło
Naprawdę podoba mi się odpowiedź SCFrench - chciałbym zaznaczyć, że można ją łatwo zmodyfikować, aby zaimportować funkcje bezpośrednio do obszaru roboczego za pomocą funkcji przypisania. (Robienie tego w ten sposób przypomina mi sposób robienia rzeczy przez Pythona „import x from y”)
A następnie wykorzystane w ten sposób:
źródło
assignin('caller',...)
byłoby bardziej poprawne. Możesz użyć tych funkcji z innej funkcji.W tym samym wierszu co odpowiedź SCFrench, ale z bardziej spinem w stylu C #.
Zrobiłbym (i często robię) klasę zawierającą wiele metod statycznych. Na przykład:
Ponieważ metody są statyczne, nie trzeba inicjować klasy. Funkcje wywołuje się w następujący sposób:
źródło
Definiuję wiele funkcji w jednym pliku .m za pomocą Octave, a następnie używam polecenia z pliku .m, w którym muszę skorzystać z funkcji z tego pliku:
Nie jestem pewien, czy jest to dostępne w Matlabie.
źródło
Możesz również pogrupować funkcje w jednym pliku głównym razem z funkcją główną, która wygląda tak:
Następnie wywołanie subfun1 wyglądałoby tak: str = main ('subfun1')
źródło
Od wersji R2017b nie jest to oficjalnie możliwe. W stosownej dokumentacji stwierdza, że:
Jednak obejścia sugerowane w innych odpowiedziach mogą osiągnąć coś podobnego.
źródło
Próbowałem z SCFRench i Ru Hashą w oktawie.
I w końcu to działa: ale dokonałem pewnych modyfikacji
Można wywołać w innym pliku „m”:
aktualizacja:
Dodałem odpowiedź, ponieważ ani +72, ani +20 nie działały dla mnie w oktawie. Ten, który napisałem, działa idealnie (i przetestowałem go w zeszły piątek, kiedy później napisałem post).
źródło