Tracks
/
Julia
Julia
/
Lehrplan
/
Funktionen
Fu

Funktionen in Julia

2 Übungen

Über Funktionen

Das Konzept Basics hat zwei Wege vorgestellt, eine Funktion zu definieren.

Ganz allgemein sieht die mehrzeilige Form so aus:

function muladd(x, y, z)
    x * y + z
end

Für kurze Definitionen gibt es die Form der „Zuweisung“, auch „Einzeiler“ genannt:

muladd(x, y, z) = x * y + z

In einer dritten, noch kürzeren Form lässt sich eine kurze Funktion, die nur einmal verwendet wird, ohne Namen erzeugen:

julia> map(x -> 2x, 1:3)
4-element Vector{Int64}:
 2
 4
 6

julia> map((x, y) -> x * y, 1:3, 4:6)
3-element Vector{Int64}:
  4
 10
 18

In diesem Fall ist x -> 2x eine „anonyme Funktion“. Das entspricht dem, was andere Sprachen als „Lambda-Funktion“ bezeichnen.

Beachte, dass mehrere Argumente runde Klammern brauchen, wie in (x, y) -> x * y.

Anonyme Funktionen sind im Julia-Code weit verbreitet, besonders in Kombination mit Funktionen höherer Ordnung wie map() und filter().

Funktionsargumente

Bisher haben wir im Lehrplan nur Funktionen betrachtet, die eine feste Anzahl von Argumenten haben und bei deren Aufruf alle Argumente in der richtigen Reihenfolge angegeben werden müssen. Das wäre einschränkend und unpraktisch, deshalb gibt es mehrere weitere Möglichkeiten.

Optionale Argumente

Wie viele Sprachen erlaubt es Julia, in der Funktionsdefinition Standardwerte für einzelne Argumente anzugeben.

Ein Funktionsaufruf kann dann entweder einen Wert für dieses Argument angeben oder es weglassen und den Standardwert verwenden.

julia> f(x, y=10) = x * y
f (generic function with 2 methods)

julia> f(2, 3)
6

julia> f(2)
20

Alle Argumente ohne Standardwert müssen vor allen Argumenten mit Standardwert stehen. f(x=2, y) wäre also ungültig.

Schlüsselwortargumente

Alle bisherigen Beispiele verwenden positional arguments, bei denen die in einem Funktionsaufruf angegebenen Werte in derselben Reihenfolge stehen müssen wie die entsprechenden Argumente in der Funktionsdefinition.

Wie viele Sprachen erlaubt Julia auch keyword arguments. Funktionsaufrufe müssen den Argumentnamen angeben, mehrere Schlüsselwortargumente kannst du dann aber in beliebiger Reihenfolge angeben.

Ein besonderes Merkmal von Julia ist, dass in der Funktionsdefinition vor den Schlüsselwortargumenten (falls vorhanden) ein Semikolon ; stehen muss, um sie von den Positionsargumenten zu trennen. In einem Funktionsaufruf kannst du zwischen dem letzten Positionsargument und dem ersten Schlüsselwortargument entweder ; oder , verwenden.

julia> b(x; y) = x + y
b (generic function with 1 method)

julia> b(2, y=3)
5

# keyword is required when calling
julia> b(2, 3)
ERROR: MethodError: no method matching b(::Int64, ::Int64)
The function `b` exists, but no method is defined for this combination of argument types.

Standardwerte kannst du optional angeben, genau wie bei Positionsargumenten.

Häufig entsteht in einem Funktionsaufruf eine Syntax wie myarg=myarg, wenn eine Variable mit demselben Namen wie der Parameter vorher berechnet wurde. In diesem Fall ist eine Kurzschreibweise erlaubt:

julia> width = 4.0
4.0

julia> height = √ width
2.0

julia> area(; width, height) = width * height
area (generic function with 1 method)

# repetition
julia> area(; width=width, height=height)
8.0

# shorthand form
julia> area(; width, height)
8.0

Splat und Slurp

Dies sind die üblichen Namen für einen nützlichen Aspekt der Julia-Syntax, falls du dich das gefragt hast. Beide beziehen sich auf den Operator ....

Splat

Splatting wird in Funktions_aufrufen_ verwendet, um Sammlungen in die einzelnen Werte zu entpacken, die die Funktion erwartet.

Das lässt sich leichter zeigen als erklären:

julia> fxyz(x, y, z) = x * y * z
fxyz (generic function with 1 method)

julia> xyz = [2, 3, 4]
3-element Vector{Int64}:
 2
 3
 4

# Using the vector directly in a function call is invalid
julia> fxyz(xyz)
ERROR: MethodError: no method matching fxyz(::Vector{Int64})
The function `fxyz` exists, but no method is defined for this combination of argument types.

# splatting converts the vector to 3 numbers, used as positional arguments
julia> fxyz(xyz...)
24

Manche „Funktionsaufrufe“ sind durch syntaktischen Zucker verborgen, deshalb lässt sich Splatting auch auf weniger offensichtliche Weise einsetzen.

Zum Beispiel nutzt die Mehrfachzuweisung intern eine Tupel-Konstruktorfunktion:

julia> first, rest... = [1, 2, 3, 4]
4-element Vector{Int64}:
 1
 2
 3
 4

julia> first
1

julia> rest
3-element Vector{Int64}:
 2
 3
 4

Schlüsselwortargumente lassen sich ebenfalls per Splatting übergeben, typischerweise mit einem named tuple. Auch ein Dict funktioniert, aber die Schlüssel müssen Symbole sein (Strings funktionieren hier nicht).

# function with 3 keyword arguments
julia> fabc(; a, b, c) = a + b + c
fabc (generic function with 1 method)

# named tuple
julia> abc_nt = (a=2, b=3, c=4)
(a = 2, b = 3, c = 4)

# there are no positional arguments, so need to use ; before kw argument
julia> fabc(;abc_nt...)
9

# Dict
julia> abc_dict = Dict(:a=>2, :b=>3, :c=>4)
Dict{Symbol, Int64} with 3 entries:
  :a => 2
  :b => 3
  :c => 4

julia> fabc(;abc_dict...)
9
Slurp

Slurping wird in der Funktions_definition_ verwendet, um eine beliebige Anzahl einzelner Werte in einer Sammlung zu bündeln.

julia> f_more(i, j, more...) = i + j + sum(more)
f_more (generic function with 1 method)

julia> f_more(1, 3, 5, 7, 9, 11)
36

Der Name des geslurpten Arguments (hier more) spielt keine Rolle. Den Typ dieser Variable wählt der Compiler, bei Positionsargumenten ist es aber wahrscheinlich tuple oder etwas Ähnliches.

Auch Schlüsselwortargumente lassen sich slurpen, was ein Dict (oder Ähnliches) ergibt.

julia> f_kwslurp(x, y; switches...) = :mult in keys(switches) ? x * y : x + y
f_kwslurp (generic function with 1 method)

julia> f_kwslurp(5, 6; mult=true)
30

julia> f_kwslurp(5, 6)
11

Im Aufruf kannst du beliebige Schlüsselwortargumente verwenden. Die Funktionsdefinition entscheidet, auf welche Schlüsselwörter sie reagiert und welche sie ignoriert.

Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab

Lerne Funktionen

Das Üben ist gesperrt

Schalte 1 weitere Übung frei, um Funktionen zu üben