Funktionen in Julia

Eine Funktion ist eine Reihe von Anweisungen, die zusammen eine Aufgabe ausführen.

In Julia ist eine Funktion ein Objekt, das ein Tupel von Argumentwerten auf einen Rückgabewert abbildet.

In Julia verwendet manfunctionDie grundlegende Syntax zum Definieren einer Funktion ist:

function functionname(args)
   expression
   expression
   expression
   ...
   expression
end

Standardmäßig ist der von einer Funktion zurückgegebene Wert der Wert des zuletzt ausgewerteten Ausdrucks, daher können Sie sehen, dass oben keinereturn-Anweisung steht. Wenn Sie natürlich dasreturn-Schlüsselwort verwenden, kehrt die Funktion sofort zurück:.

Beispiel

julia> function f(x,y)
           x + y
       end
f (generische Funktion mit 1 Methode)
julia> f(2,3)
5

julia> function bills(money)
      if money < 0
         return false
      else
         return true
      end
   end
bills (generic function with 1 method)

julia> bills(50)
wahr

julia> bills(-50)
false

Wenn eine Funktion mehrere Werte zurückgeben muss, können Sie ein Tupel verwenden:

Beispiel

julia> function mul(x,y)
                  x+y, x*y
               end
mul (generische Funktion mit 1 Methode)

julia> mul(5, 10)
(15, 50)

Wenn eine Funktion nur einen Ausdruck enthält, können Sie dasfunction-Schlüsselwort weglassen, den Funktionsnamen und die Parameter auf die linke Seite des Gleichheitszeichens setzen und den Ausdruck auf die rechte Seite setzen, ähnlich einer Zuweisungsform:

julia> f(x,y) = x + y
f (generic function with 1 method)

Wenn keine Klammern vorhanden sind,fbezieht sich der Ausdruck auf das Funktionsobjekt, das wie jeder Wert weitergegeben werden kann:

julia> g = f;
julia> g(2,3)
5

Beispiel

julia> f(a) = a * a
f (generische Funktion mit 1 Methode)

julia> f(5)
25

julia> func(x, y) = sqrt(x^2 + y^2)
func (generische Funktion mit 1 Methode)

julia> func(5, 4)
6.4031242374328485

Wie Variablennamen können auch Unicode-Zeichen als Funktionsnamen verwendet werden:

julia> ∑(x,y) = x + y
∑ (generic function with 1 method)

julia> ∑(2, 3)
5

Rückgabetyp

Wir können den::Operator verwenden, um den Rückgabetyp der Funktion anzugeben.

Beispiel

julia> function g(x, y)::Int8
           return x * y
       end;

julia> typeof(g(1, 2))
Int8

Das obige Funktionsbeispiel ignoriert die Typen von x und y und gibt einen Wert vom Typ Int8 zurück.

Optionale Argumente

In Funktionen können wir Standardwerte für Parameter festlegen, sodass der Standardwert für die Berechnung verwendet werden kann, wenn der Parameter nicht angegeben wird:

Das folgende Beispiel definiert eine Funktion pos mit drei Parametern, wobei der Parameter cz einen Standardwert von 0 hat. Beim Aufruf der Funktion kann dieser Parameter weggelassen werden:

Beispiel

julia> function pos(ax, by, cz=0)
         println("$ax, $by, $cz")
      end
pos (generische Funktion mit 2 Methoden)

julia> pos(10, 30)
10, 30, 0

julia> pos(10, 30, 50)
10, 30, 50

Schlüsselwortargumente

Manchmal erfordern die Funktionen, die wir definieren, eine große Anzahl von Argumenten, aber der Aufruf dieser Funktionen kann mühsam sein, weil wir die Reihenfolge vergessen könnten, in der die Argumente übergeben werden. Zum Beispiel:

function foo(a, b, c, d, e, f)
...
end

Wir könnten die Reihenfolge der Argumente vergessen, was zu folgendem Funktionsaufruf führt:

foo("25", -5.6987, "hello", 56, good, 'ABC')
oder 
foo("hello", 56, "25", -5.6987, 'ABC', good)

Das sieht sehr verwirrend aus.

Julia-Schlüsselwortargumente ermöglichen es, Argumente anhand ihres Namens statt nur anhand ihrer Position zu identifizieren, wodurch diese komplexen Funktionen einfach zu verwenden und zu erweitern sind.

Um Argumente mit Schlüsselwörtern zu markieren, müssen Sie ein Semikolon nach den unmarkierten Argumenten der Funktion;verwenden, gefolgt von einem oder mehreren Schlüssel-Wert-Paarenkey=value, wie unten gezeigt:

Beispiel

julia> function foo(a, b ; c = 10, d = "hi")
         println("a is $a")
         println("b is $b")
         return "c => $c, d => $d"
      end
foo (generische Funktion mit 1 Methode)

julia> foo(100,20)
a is 100
b is 20
"c => 10, d => hi"

julia> foo("Hello", "Example", c=pi, d=22//7)
a ist Hello
b ist Example
"c => π, d => 22//7"

Bei Schlüsselwortargumenten ist die Position der Argumente nicht so wichtig. Wir können die obige Funktion auch so aufrufen:

Beispiel

julia> foo(c=pi, d =22/7, "Hello", "Example")
a ist Hello
b ist Example
"c => π, d => 3.142857142857143"

Anonyme Funktionen

Eine anonyme Funktion ist eine Funktion ohne Funktionsnamen.

Anonyme Funktionen werden zur Laufzeit dynamisch deklariert. Abgesehen davon, dass sie keinen Funktionsnamen haben, sind sie dieselben wie Standardfunktionen.

In Julia können anonyme Funktionen an vielen Stellen verwendet werden, wie zum Beispiel in map() und Listenkomprehensionen.

Nach der Verwendung anonymer Funktionen wird unser Code prägnanter.

Die Syntax anonymer Funktionen verwendet das Symbol->。

Beispiel

julia> x -> x^2 + 2x - 1
#1 (generische Funktion mit 1 Methode)

julia> function (x)
           x^2 + 2x - 1
       end
#3 (generische Funktion mit 1 Methode)

Das obige Beispiel erstellt eine Funktion, die einen Parameter akzeptiertxund das Polynom des aktuellen Werts zurückgibtx^2+2x-1Funktion.

Der Hauptverwendungszweck anonymer Funktionen besteht darin, sie an Funktionen zu übergeben, die Funktionen als Argumente empfangen. Ein klassisches Beispiel ist map, das eine Funktion auf jedes Element eines Arrays anwendet und dann ein neues Array mit den resultierenden Werten zurückgibt:

Beispiel

julia> map(round, [1.2, 3.5, 1.7])
3-Element Vector{Float64}:
 1.0
 4.0
 2.0

Wenn die als erstes Argument an map übergebene Transformationsfunktion bereits existiert, ist die direkte Verwendung des Funktionsnamens in Ordnung. Aber normalerweise ist die zu verwendende Funktion noch nicht definiert, daher ist die Verwendung einer anonymen Funktion bequemer:

Beispiel

julia> map(x -> x^2 + 2x - 1, [1, 3, -1])
3-elementiger Vector{Int64}:
  2
 14
 -2

Anonyme Funktionen, die mehrere Argumente akzeptieren, können mit der Syntax (x,y,z)->2x+y-z geschrieben werden, während nullargumentige anonyme Funktionen als ()->3 geschrieben werden. Diese Schreibweise für nullargumentige Funktionen mag etwas seltsam aussehen, ist aber für die Lazy Evaluation sehr notwendig. Diese Verwendung verpackt einen Codeblock in eine nullargumentige Funktion und ruft sie später als f auf.

Betrachten Sie zum Beispiel den Aufruf von get:

Beispiel

get(dict, key) do
    # Standardwert hier berechnet
    time()
end

Der obige Code entspricht dem Aufruf von get mit einer anonymen Funktion, die den Code enthält. Er ist zwischen do und end eingeschlossen, wie unten gezeigt:

get(()->time(), dict, key)

Hier wird der Aufruf von time durch eine anonyme Funktion ohne Argumente verzögert, die ihn umschließt. Diese anonyme Funktion wird nur aufgerufen, wenn dict den angeforderten Schlüssel nicht enthält.


Funktionsverschachtelung und Rekursion

In Julia können Funktionen verschachtelt werden.

Das folgende Beispiel verschachtelt eine add1-Funktion in die add()-Funktion:

Beispiel

julia> function add(x)
         Y = x * 2
         function add1(Y)
           Y += 1
         end
         add1(Y)
       end
add (generische Funktion mit 1 Methode)

julia> d = 10
10

julia> add(d)
21

Ähnlich können Funktionen in Julia auch rekursiv sein.

Rekursion bezeichnet die Methode, die Funktion selbst innerhalb der Definition einer Funktion zu verwenden.

Zum Beispiel:
Es war einmal ein Berg, in dem Berg war ein Tempel, in dem Tempel war ein alter Mönch, der einem jungen Mönch eine Geschichte erzählte! Was war die Geschichte? "Es war einmal ein Berg, in dem Berg war ein Tempel, in dem Tempel war ein alter Mönch, der einem jungen Mönch eine Geschichte erzählte! Was war die Geschichte? 'Es war einmal ein Berg, in dem Berg war ein Tempel, in dem Tempel war ein alter Mönch, der einem jungen Mönch eine Geschichte erzählte! Was war die Geschichte? ...'"

Unten verwenden wir den ternären Operator, um Rekursion zu testen. Der ternäre Operator arbeitet mit drei Operandenexpr ? a : b, wenn expr wahr ist, ist der Wert das Ergebnis der Auswertung von a, andernfalls ist er das Ergebnis der Auswertung von b.

Beispiel

julia> sum(x) = x > 1 ? sum(x-1) + x : x
sum (generische Funktion mit 1 Methode)

julia> sum(10)
55

Das obige Beispiel wird verwendet, um die Summe aller Zahlen bis einschließlich einer bestimmten ganzen Zahl zu berechnen. In dieser Rekursion wird, weil es einen Basisfall gibt, das heißt, wenn x 1 ist, dieser Wert zurückgegeben.

Das bekannteste Beispiel für Rekursion ist die Berechnung der n-ten Fibonacci-Zahl. Die Fibonacci-Folge ist eine Folge wie diese: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368........

Ab dem 3. Glied ist jedes Glied dieser Folge gleich der Summe der beiden vorherigen Glieder.

Beispiel

julia> fib(x) = x < 2 ? x : fib(x-1) + fib(x-2)
fib (generische Funktion mit 1 Methode)

julia> fib(10)
55

julia> fib(20)
6765

Map

Das Definitionsformat von Map ist wie folgt:

map(func, coll)

Hier ist func eine Funktion, die nacheinander auf jedes Element der Sammlung coll angewendet wird. Map enthält im Allgemeinen eine anonyme Funktion und gibt eine neue Sammlung zurück.

Beispiel

julia> map(A -> A^3 + 3A - 3, [10,3,-2])
3-element Array{Int64,1}:
 1027
   33
  -17

Filter

Das Definitionsformat von Filter ist wie folgt:

filter(function, collection)

Die filter-Funktion gibt eine Kopie der Sammlung zurück und entfernt Elemente, für die das Ergebnis des Aufrufs der Funktion false ist.

Beispiel

julia> array = Int[1,2,3]
3-element Array{Int64,1}:
 1
 2
 3
 
julia> filter(x -> x % 2 == 0, array)
1-element Array{Int64,1}:
 2
Andere Erweiterungen