复合类型 #

一、不可变结构体 #

1.1 定义struct #

julia
struct Point
    x::Float64
    y::Float64
end

1.2 创建实例 #

julia
p = Point(1.0, 2.0)
p.x
p.y

1.3 不可变性 #

julia
p = Point(1.0, 2.0)
p.x = 10.0

1.4 默认字段类型 #

julia
struct Person
    name
    age
end

p = Person("Alice", 25)
typeof(p.name)
typeof(p.age)

二、可变结构体 #

2.1 定义mutable struct #

julia
mutable struct MutablePoint
    x::Float64
    y::Float64
end

2.2 修改字段 #

julia
p = MutablePoint(1.0, 2.0)
p.x = 10.0
p.y = 20.0
p

2.3 可变性对比 #

julia
struct ImmutablePoint
    x::Float64
    y::Float64
end

p1 = ImmutablePoint(1.0, 2.0)
p1.x = 10.0

p2 = MutablePoint(1.0, 2.0)
p2.x = 10.0

三、构造函数 #

3.1 默认构造函数 #

julia
struct Point
    x::Float64
    y::Float64
end

p = Point(1.0, 2.0)

3.2 自定义构造函数 #

julia
struct Point
    x::Float64
    y::Float64
    
    Point(x::Real, y::Real) = new(Float64(x), Float64(y))
    Point(x::Real) = new(Float64(x), Float64(x))
end

Point(1, 2)
Point(5)

3.3 外部构造函数 #

julia
struct Point
    x::Float64
    y::Float64
end

Point(x::Real) = Point(Float64(x), Float64(x))
Point() = Point(0.0, 0.0)

Point()
Point(5)

3.4 内部构造函数 #

julia
struct PositiveNumber
    value::Float64
    
    function PositiveNumber(x::Real)
        x > 0 || error("Value must be positive")
        new(Float64(x))
    end
end

PositiveNumber(5)
PositiveNumber(-1)

四、字段默认值 #

4.1 使用外部构造函数 #

julia
struct Config
    host::String
    port::Int
    debug::Bool
end

Config(host::String) = Config(host, 8080, false)
Config() = Config("localhost", 8080, false)

Config()
Config("example.com")
Config("example.com", 443, true)

4.2 使用@kwdef宏 #

julia
using Base: @kwdef

@kwdef struct ServerConfig
    host::String = "localhost"
    port::Int = 8080
    debug::Bool = false
end

ServerConfig()
ServerConfig(host="example.com")
ServerConfig(port=443, debug=true)

五、方法定义 #

5.1 为类型定义方法 #

julia
struct Point
    x::Float64
    y::Float64
end

Base.:+(p1::Point, p2::Point) = Point(p1.x + p2.x, p1.y + p2.y)
Base.:*(p::Point, s::Real) = Point(p.x * s, p.y * s)

Point(1.0, 2.0) + Point(3.0, 4.0)
Point(1.0, 2.0) * 2

5.2 自定义显示 #

julia
struct Point
    x::Float64
    y::Float64
end

Base.show(io::IO, p::Point) = print(io, "Point($(p.x), $(p.y))")

Point(1.0, 2.0)

5.3 转换方法 #

julia
struct Point
    x::Float64
    y::Float64
end

Base.convert(::Type{Point}, t::Tuple) = Point(t[1], t[2])

p = convert(Point, (1.0, 2.0))

六、实践练习 #

6.1 练习1:复数类型 #

julia
struct MyComplex
    real::Float64
    imag::Float64
end

Base.:+(a::MyComplex, b::MyComplex) = MyComplex(a.real + b.real, a.imag + b.imag)
Base.:*(a::MyComplex, b::MyComplex) = MyComplex(
    a.real * b.real - a.imag * b.imag,
    a.real * b.imag + a.imag * b.real
)
Base.abs(c::MyComplex) = sqrt(c.real^2 + c.imag^2)
Base.show(io::IO, c::MyComplex) = print(io, "$(c.real) + $(c.imag)im")

c1 = MyComplex(1, 2)
c2 = MyComplex(3, 4)
c1 + c2
c1 * c2
abs(c1)

6.2 练习2:银行账户 #

julia
mutable struct BankAccount
    owner::String
    balance::Float64
    
    function BankAccount(owner::String, initial_balance::Real=0.0)
        initial_balance >= 0 || error("Initial balance cannot be negative")
        new(owner, Float64(initial_balance))
    end
end

function deposit!(account::BankAccount, amount::Real)
    amount > 0 || error("Amount must be positive")
    account.balance += amount
    return account.balance
end

function withdraw!(account::BankAccount, amount::Real)
    amount > 0 || error("Amount must be positive")
    amount <= account.balance || error("Insufficient funds")
    account.balance -= amount
    return account.balance
end

account = BankAccount("Alice", 1000.0)
deposit!(account, 500.0)
withdraw!(account, 200.0)

6.3 练习3:矩形 #

julia
struct Rectangle
    width::Float64
    height::Float64
    
    function Rectangle(w::Real, h::Real)
        w > 0 && h > 0 || error("Dimensions must be positive")
        new(Float64(w), Float64(h))
    end
end

area(r::Rectangle) = r.width * r.height
perimeter(r::Rectangle) = 2 * (r.width + r.height)
Base.show(io::IO, r::Rectangle) = print(io, "Rectangle($(r.width) × $(r.height))")

r = Rectangle(3.0, 4.0)
area(r)
perimeter(r)

七、总结 #

本章我们学习了:

  1. 不可变struct:定义不可变结构体
  2. 可变mutable struct:定义可变结构体
  3. 构造函数:内部和外部构造函数
  4. 字段默认值:使用@kwdef宏
  5. 方法定义:为类型添加方法

接下来让我们学习Julia的抽象类型!

最后更新:2026-03-27