Julia 函数
函数是 Julia 程序的基本构建块。Julia 的函数功能强大,支持多种定义方式和高级特性。
函数定义
基本定义
julia
# 标准定义
function greet(name)
println("Hello, $name!")
end
greet("Julia") # Hello, Julia!
# 带返回值
function add(a, b)
return a + b
end
result = add(3, 5)
println(result) # 8
# 最后一个表达式自动返回
function multiply(a, b)
a * b # 不需要 return
end简短定义
julia
# 单行函数定义
add(a, b) = a + b
square(x) = x^2
println(add(3, 5)) # 8
println(square(4)) # 16
# 更复杂的单行函数
distance(x, y) = sqrt(x^2 + y^2)
println(distance(3, 4)) # 5.0匿名函数
julia
# 使用 -> 语法
f = x -> x^2
println(f(5)) # 25
# 多参数
add = (x, y) -> x + y
println(add(3, 4)) # 7
# 在高阶函数中使用
numbers = [1, 2, 3, 4, 5]
squares = map(x -> x^2, numbers)
println(squares) # [1, 4, 9, 16, 25]
# 使用 function 定义匿名函数
f = function(x, y)
x + y
end参数
位置参数
julia
function describe(name, age, city)
println("$name is $age years old and lives in $city")
end
describe("Alice", 30, "Beijing")默认参数
julia
function greet(name, greeting="Hello")
println("$greeting, $name!")
end
greet("Julia") # Hello, Julia!
greet("Julia", "Hi") # Hi, Julia!
# 多个默认参数
function create_user(name, age=18, active=true)
return (name=name, age=age, active=active)
end
println(create_user("Bob")) # (name = "Bob", age = 18, active = true)
println(create_user("Alice", 25)) # (name = "Alice", age = 25, active = true)关键字参数
使用分号 ; 分隔位置参数和关键字参数:
julia
function create_user(name; age=18, city="Unknown")
return (name=name, age=age, city=city)
end
# 必须使用关键字名称
println(create_user("Alice"))
println(create_user("Bob", age=25))
println(create_user("Charlie", city="Shanghai", age=30))
# 必需的关键字参数(无默认值)
function connect(; host, port)
println("Connecting to $host:$port")
end
connect(host="localhost", port=8080)可变参数
julia
# 位置可变参数
function sum_all(args...)
total = 0
for x in args
total += x
end
return total
end
println(sum_all(1, 2, 3)) # 6
println(sum_all(1, 2, 3, 4, 5)) # 15
# 关键字可变参数
function print_kwargs(; kwargs...)
for (key, value) in kwargs
println("$key = $value")
end
end
print_kwargs(a=1, b=2, c=3)
# 展开参数
args = (1, 2, 3)
println(sum_all(args...)) # 6
kwargs = (a=1, b=2)
print_kwargs(; kwargs...)返回值
单个返回值
julia
function double(x)
return x * 2
end多个返回值
julia
# 返回元组
function minmax(a, b)
if a < b
return (a, b)
else
return (b, a)
end
end
result = minmax(5, 3)
println(result) # (3, 5)
# 解构返回值
min_val, max_val = minmax(5, 3)
println("min: $min_val, max: $max_val")
# 返回命名元组
function analyze(data)
return (
min = minimum(data),
max = maximum(data),
avg = sum(data) / length(data)
)
end
result = analyze([1, 2, 3, 4, 5])
println(result.avg) # 3.0无返回值
julia
function print_hello()
println("Hello!")
# 隐式返回 nothing
end
result = print_hello()
println(result) # nothing类型注解
参数类型
julia
function add(a::Int, b::Int)
return a + b
end
println(add(3, 5)) # 8
# add(3.0, 5.0) # 错误!类型不匹配
# 抽象类型
function add_numbers(a::Number, b::Number)
return a + b
end
println(add_numbers(3, 5.0)) # 8.0返回类型
julia
function divide(a, b)::Float64
return a / b
end
result = divide(10, 3)
println(typeof(result)) # Float64参数化类型
julia
function first_element(arr::Vector{T}) where T
return arr[1]::T
end
println(first_element([1, 2, 3])) # 1
println(first_element(["a", "b"])) # "a"多重派发
Julia 的核心特性之一是多重派发:根据所有参数的类型选择方法。
julia
# 定义多个方法
describe(x::Int) = "整数: $x"
describe(x::Float64) = "浮点数: $x"
describe(x::String) = "字符串: $x"
describe(x) = "未知类型: $x"
println(describe(42)) # 整数: 42
println(describe(3.14)) # 浮点数: 3.14
println(describe("hello")) # 字符串: hello
println(describe([1,2,3])) # 未知类型: [1, 2, 3]
# 多参数派发
multiply(a::Int, b::Int) = "两个整数: $(a * b)"
multiply(a::Float64, b::Float64) = "两个浮点: $(a * b)"
multiply(a::Int, b::Float64) = "混合类型: $(a * b)"
println(multiply(3, 4)) # 两个整数: 12
println(multiply(3.0, 4.0)) # 两个浮点: 12.0
println(multiply(3, 4.0)) # 混合类型: 12.0查看方法
julia
# 查看函数的所有方法
println(methods(describe))
# 查看特定类型的方法
println(@which describe(42))高阶函数
函数作为参数
julia
function apply_twice(f, x)
return f(f(x))
end
println(apply_twice(x -> x + 1, 5)) # 7
println(apply_twice(x -> x * 2, 3)) # 12函数作为返回值
julia
function make_multiplier(n)
return x -> x * n
end
double = make_multiplier(2)
triple = make_multiplier(3)
println(double(5)) # 10
println(triple(5)) # 15常用高阶函数
julia
arr = [1, 2, 3, 4, 5]
# map - 映射
println(map(x -> x^2, arr)) # [1, 4, 9, 16, 25]
# filter - 过滤
println(filter(x -> x > 2, arr)) # [3, 4, 5]
# reduce - 归约
println(reduce(+, arr)) # 15
# foreach - 遍历(无返回值)
foreach(println, arr)
# any / all - 条件检查
println(any(x -> x > 3, arr)) # true
println(all(x -> x > 0, arr)) # truedo 语法
用于传递多行匿名函数:
julia
# 使用 do 块
result = map([1, 2, 3]) do x
y = x^2
y + 1
end
println(result) # [2, 5, 10]
# 等价于
result = map(x -> begin
y = x^2
y + 1
end, [1, 2, 3])
# 文件操作中常用
open("test.txt", "w") do f
write(f, "Hello, Julia!")
end闭包
函数可以捕获外部变量:
julia
function make_counter()
count = 0
return function()
count += 1
return count
end
end
counter = make_counter()
println(counter()) # 1
println(counter()) # 2
println(counter()) # 3
# 另一个独立计数器
counter2 = make_counter()
println(counter2()) # 1函数组合
julia
# 使用 ∘ 组合函数
f = sqrt ∘ abs
println(f(-16)) # 4.0(先取绝对值,再开方)
# 链式组合
g = uppercase ∘ strip ∘ string
println(g(42)) # "42"
# 管道运算符
result = -16 |> abs |> sqrt
println(result) # 4.0递归
julia
# 阶乘
function factorial(n)
if n <= 1
return 1
else
return n * factorial(n - 1)
end
end
println(factorial(5)) # 120
# 斐波那契(带记忆化)
function fib(n, memo=Dict{Int,Int}())
if n <= 2
return 1
end
if haskey(memo, n)
return memo[n]
end
result = fib(n-1, memo) + fib(n-2, memo)
memo[n] = result
return result
end
println(fib(50)) # 12586269025内置函数操作
julia
# 函数信息
println(methods(+)) # 查看所有 + 方法
# 方法查找
@which 1 + 2 # 查看使用的具体方法
# 参数信息
# 使用 ? 在 REPL 中查看函数文档文档字符串
julia
"""
add(a, b)
计算两个数的和。
# 参数
- `a`: 第一个数
- `b`: 第二个数
# 返回值
返回 a 和 b 的和。
# 示例
```julia
julia> add(2, 3)
5""" function add(a, b) return a + b end
在 REPL 中使用 ? add 查看文档
## 下一步
学习完函数后,请继续学习:
- [流程控制](julia-control-flow) - 条件和循环
- [元编程](julia-metaprogramming) - 宏和代码生成
- [数据类型](julia-data-types) - 类型在函数中的应用