Structs: eigene Typen
struct Punkt # unveränderlich (immutable)
x::Float64
y::Float64
end
mutable struct Konto # veränderlich
inhaber::String
stand::Float64
end
abstract type Form end
struct Kreis <: Form; r::Float64 end
struct Rechteck <: Form; b::Float64; h::Float64 end
flaeche(k::Kreis) = π * k.r^2
flaeche(r::Rechteck) = r.b * r.h
umfang(k::Kreis) = 2π * k.r
umfang(r::Rechteck) = 2 * (r.b + r.h)
p = Punkt(3, 4)
println(p, " ", p.x, " ", typeof(p), " ", fieldnames(Punkt))
k = Konto("Mia", 100.0)
k.stand += 50
println(k.inhaber, " ", k.stand, " ", ismutable(k), " ", ismutable(p))
formen = [Kreis(1.0), Rechteck(3.0, 4.0), Kreis(2.5)]
for f in formen
println(typeof(f), ": Fläche ", round(flaeche(f), digits = 2), ", Umfang ", round(umfang(f), digits = 2))
end
println(sum(flaeche, formen) |> x -> round(x, digits = 3))
println(sort(formen, by = flaeche) .|> typeof)
# Konstruktoren mit Prüfung und Standardwerten
struct Person
name::String
alter::Int
function Person(name, alter)
alter < 0 && throw(ArgumentError("Alter darf nicht negativ sein"))
new(name, alter)
end
end
Person(name) = Person(name, 18)
println(Person("Tom"), " ", Person("Zoe", 31).alter)
try
Person("Ben", -5)
catch e
println(typeof(e), ": ", e.msg)
end
# Parametrische Typen
struct Paar{A, B}
erstes::A
zweites::B
end
println(Paar(1, "eins"), " ", typeof(Paar(1.5, :x)))
using Printf
Base.show(io::IO, p::Punkt) = @printf(io, "Punkt(%.1f, %.1f)", p.x, p.y)
println(p, " ", [Punkt(1, 2), Punkt(3, 4)])Punkt(3.0, 4.0) 3.0 Punkt (:x, :y)
Mia 150.0 true false
Kreis: Fläche 3.14, Umfang 6.28
Rechteck: Fläche 12.0, Umfang 14.0
Kreis: Fläche 19.63, Umfang 15.71
34.777
DataType[Kreis, Rechteck, Kreis]
Person("Tom", 18) 31
ArgumentError: Alter darf nicht negativ sein
Paar{Int64, String}(1, "eins") Paar{Float64, Symbol}
Punkt(3.0, 4.0) Punkt[Punkt(1.0, 2.0), Punkt(3.0, 4.0)]Julia hat keine Klassen mit Methoden im Objekt: Daten (struct) und Verhalten (Funktionen mit Mehrfachverteilung) sind getrennt. Vererbung gibt es nur für abstrakte Typen (Hierarchie), nicht für Felder; für Wiederverwendung nutzt man Komposition.
Fehlerbehandlung
function teile(a, b)
b == 0 && throw(DivideError())
return a / b
end
try
println(teile(10, 2))
println(teile(1, 0))
catch e
println("Fehler: ", typeof(e))
finally
println("finally")
end
function lies_zahl(s)
try
return parse(Int, s)
catch e
e isa ArgumentError || rethrow()
return nothing
end
end
println(lies_zahl("42"), " ", lies_zahl("x"))
struct MeinFehler <: Exception
code::Int
text::String
end
Base.showerror(io::IO, e::MeinFehler) = print(io, "MeinFehler $(e.code): $(e.text)")
try
throw(MeinFehler(404, "nicht gefunden"))
catch e
println(sprint(showerror, e), " | ", e.code)
end
x = tryparse(Float64, "3.5")
println(x, " ", tryparse(Float64, "abc"), " ", something(tryparse(Int, "q"), -1))
@assert 1 + 1 == 2 "Mathe kaputt"
println(isa(try error("boom") catch e e end, ErrorException))
println(try [1, 2, 3][5] catch e typeof(e) end)
println(try sqrt(-1) catch e typeof(e) end)
println(try Int("x") catch e typeof(e) end)
println(try undefined_variable catch e typeof(e) end)
println(try 1 + "a" catch e typeof(e) end)5.0 Fehler: DivideError finally 42 nothing MeinFehler 404: nicht gefunden | 404 3.5 nothing -1 true BoundsError DomainError MethodError UndefVarError MethodError
Module und Pakete
Ein Modul ist ein eigener Namensraum. Pakete laden mit using (alle exportierten Namen) oder import (nur Modulnamen):
module Geometrie
export kreisflaeche, PI2
const PI2 = 2π
kreisflaeche(r) = π * r^2
hilfsfunktion(x) = x + 1 # nicht exportiert
end
using .Geometrie # lokales Modul: mit Punkt
println(kreisflaeche(2.0) |> x -> round(x, digits = 3), " ", PI2 |> x -> round(x, digits = 3))
println(Geometrie.hilfsfunktion(1))
using Statistics, Random, Dates
println(mean([1, 2, 3, 4]), " ", median([3, 1, 2]), " ", std([2, 4, 4, 4, 5, 5, 7, 9]) |> x -> round(x, digits = 4), " ", var([1, 2, 3, 4]))
Random.seed!(42)
println(length(rand(5)), " ", all(0 .<= rand(100) .< 1), " ", randperm(5) |> sort)
println(Date(2025, 3, 15) + Day(20), " ", dayofweek(Date(2025, 3, 15)), " ", Date(2025, 12, 24) - Date(2025, 3, 15))12.566 6.283 2 2.5 2.0 2.1381 1.6666666666666667 5 true [1, 2, 3, 4, 5] 2025-04-04 6 284 days
Weitere Standardbibliotheken: LinearAlgebra, Statistics, Random, Dates, Printf, Test, Distributed, SparseArrays, Downloads, Pkg.
Merke
struct(unveränderlich) undmutable struct; abstrakte Typen bilden Hierarchien- Verhalten steckt in Funktionen mit Mehrfachverteilung, nicht im Objekt
- Eigene Konstruktoren mit
new(...), parametrische TypenPaar{A, B} try/catch/finally,throw,rethrow(),tryparse- Module:
module ... end,export,using,import
Aufgabe
Definiere einen abstrakten Typ Tier mit zwei konkreten Typen und einer Funktion laut.