ZetCode

Julia 接口教程

最后修改时间:2025年3月3日

在 Julia 中,接口是非正式的契约,它定义了一组方法,一个类型必须实现这些方法才能满足特定的行为。与其他语言不同,Julia 不显式强制执行接口。相反,它们是约定。

接口对于多态至关重要,它允许不同类型在实现所需方法时可以互换使用。

迭代接口

迭代接口要求实现 iterateBase.IteratorSize

main.jl
struct MyRange
    start::Int
    stop::Int
end

Base.iterate(r::MyRange, state=r.start) = state > r.stop ? nothing : (state, state + 1)
Base.IteratorSize(::Type{MyRange}) = Base.HasLength()

此示例定义了一个支持迭代的自定义范围类型。

索引接口

索引接口要求实现 getindexsetindex!

main.jl
struct MyArray
    data::Vector{Int}
end

Base.getindex(a::MyArray, i::Int) = a.data[i]
Base.setindex!(a::MyArray, v::Int, i::Int) = a.data[i] = v

此示例定义了一个支持索引的自定义数组类型。

AbstractArray 接口

AbstractArray 接口要求实现 sizegetindex 等方法。

main.jl
struct MyMatrix
    data::Matrix{Int}
end

Base.size(m::MyMatrix) = size(m.data)
Base.getindex(m::MyMatrix, i::Int, j::Int) = m.data[i, j]

此示例定义了一个表现得像数组的自定义矩阵类型。

AbstractFloat 接口

AbstractFloat 接口要求实现 +-* 等方法。

main.jl
struct MyFloat
    value::Float64
end

Base.:+(a::MyFloat, b::MyFloat) = MyFloat(a.value + b.value)
Base.:-(a::MyFloat, b::MyFloat) = MyFloat(a.value - b.value)
Base.:*(a::MyFloat, b::MyFloat) = MyFloat(a.value * b.value)

此示例定义了一个具有算术运算的自定义浮点类型。

AbstractString 接口

AbstractString 接口要求实现 ncodeunitscodeunit 等方法。

main.jl
struct MyString
    data::String
end

Base.ncodeunits(s::MyString) = ncodeunits(s.data)
Base.codeunit(s::MyString, i::Int) = codeunit(s.data, i)

此示例定义了一个表现得像标准字符串的自定义字符串类型。

AbstractDict 接口

AbstractDict 接口要求实现 gethaskey 等方法。

main.jl
struct MyDict
    data::Dict{String, Int}
end

Base.get(d::MyDict, key::String, default) = get(d.data, key, default)
Base.haskey(d::MyDict, key::String) = haskey(d.data, key)

此示例定义了一个支持键值查找的自定义字典类型。

AbstractSet 接口

AbstractSet 接口要求实现 inlength 等方法。

main.jl
struct MySet
    data::Set{Int}
end

Base.in(x::Int, s::MySet) = x in s.data
Base.length(s::MySet) = length(s.data)

此示例定义了一个支持成员资格检查的自定义集合类型。

AbstractChannel 接口

AbstractChannel 接口要求实现 put!take! 等方法。

main.jl
struct MyChannel
    data::Channel{Int}
end

Base.put!(c::MyChannel, x::Int) = put!(c.data, x)
Base.take!(c::MyChannel) = take!(c.data)

此示例定义了一个用于任务间通信的自定义通道类型。

AbstractIO 接口

AbstractIO 接口要求实现 readwrite 等方法。

main.jl
struct MyIO
    data::IOBuffer
end

Base.read(io::MyIO, n::Int) = read(io.data, n)
Base.write(io::MyIO, x::UInt8) = write(io.data, x)

此示例定义了一个用于读写数据的自定义 I/O 类型。

AbstractTask 接口

AbstractTask 接口要求实现 schedulewait 等方法。

main.jl
struct MyTask
    task::Task
end

Base.schedule(t::MyTask) = schedule(t.task)
Base.wait(t::MyTask) = wait(t.task)

此示例定义了一个用于异步执行的自定义任务类型。

接口的最佳实践

来源

Julia 接口文档

在本教程中,我们通过实际示例探讨了 Julia 接口,涵盖了迭代、索引、数组等。接口可实现 Julia 中灵活且可重用的代码。

作者

我叫 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Julia 教程